简单链表的数据结构
要在C语言中使用链表,首先从定义一个链表开始。链表中通常包含节点,节点中有节点的值和指向下一个节点的指针。
如下的代码示例定义了一个1)包含指向下一个节点指针的,2)包含一个整型index和16个字节长度字符串name的节点的结构体。
typedef struct linked_list_s {
struct linked_list_s *p_next; // 指向链表中的下一个节点
int index;
char name[16];
} linked_list;
其中,typedef是C语言中的关键字,相当于把这个结构体起了一个简单的名字叫做linked_list。后续的代码可以将这个linked_list当一个新的“结构体类型”来用。
创建链表节点
这段代码比较简洁,主要作用是在内存中创建一个节点。malloc函数在<stdlib.h>头文件中(关于C语言中基本函数所在的头文件引用,可以参考我的上一篇文章 【由浅入深C系列一】C标准库(C99 )接口的头文件集和功能定义参考),包含这个文件即可以使用这个系统函数。
linked_list* create_node() {
return (linked_list*)malloc(sizeof(linked_list));
}
设置链表结点
为了方便说明,通过注释在代码中进行说明。
linked_list* p_head = create_node(); // 头指针,指向链表的第一个元素
linked_list* p_cur = p_head;
p_cur->next = create_node(); // 依次创建4个节点,并对节点元素赋值
p_cur = p_cur->next; // 将当前节点的指针指向,从头指针移向当前创建的新节点
p_cur->index = 1; // 通过当前指针,对新节点进行赋值操作
strcpy(p_cur->name, "Test node");
p_cur->next = p_head; // 将当前创建的新节点的下一个节点指向头指针,以确保为一个链表
p_cur->next = create_node();
p_cur = p_cur->next;
p_cur->index = 2;
strcpy(p_cur->name, "Test node");
p_cur->next = p_head;
p_cur->next = create_node();
p_cur = p_cur->next;
p_cur->index = 3;
strcpy(p_cur->name, "Test node");
p_cur->next = p_head;
p_cur->next = create_node();
p_cur = p_cur->next;
p_cur->index = 4;
strcpy(p_cur->name, "Test node");
p_cur->next = p_head;
遍历链表
通过一个循环,遍历链表中的每个节点,直到达到链表头。遍历过程中打印出:当前指针的地址,下一个节点指针的地址,当前节点的index和name值。
for (linked_list* p = p_head->p_next; p != p_head; p = p->p_next) {
printf("[%x -> %x] %d %s\n", p, p->p_next, p->index, p->name);
}
运行结果

优化一下
把设置节点的语句抽出来重构成函数调用。
linked_list* set_node(const linked_list* head, linked_list* current, int index, char* name) {
current->next = create_node(); // 当前节点的下一个节点指针,指向新创建的节点
current = current->next; // 当前指针前移,变成新创建的节点本身
current->index = index; // 以下二行是赋值
strcpy(current->name, name);
current->next = head; // 新节点的下一个节点指针,指向头指针,链表变成环型
return current; // 返回新节点的指针
}
优化后的设置过程,代码简洁许多,逻辑也更加清晰。运行结果和上面一样,有兴趣的同学可以试试。
linked_list* p_head = create_node();
linked_list* p_cur = p_head;
p_cur = set_node(p_head, p_cur, 1, "Test node.");
p_cur = set_node(p_head, p_cur, 2, "Test node.");
p_cur = set_node(p_head, p_cur, 3, "Test node.");
p_cur = set_node(p_head, p_cur, 4, "Test node.");
完整的源代码文件
linked_list.h
#ifndef __LINKED_LIST_H__
#define __LINKED_LIST_H__
#include <stdlib.h>
/*--------------------------------------------------
linked list methods.
--------------------------------------------------*/
#ifndef MAX_SHORT_NAME
#define MAX_SHORT_NAME 256
#endif
typedef struct linked_list_s {
struct linked_list_s *next;
int index;
char name[MAX_SHORT_NAME];
} linked_list;
linked_list* create_node();
int set_node(const linked_list* head, int index, char* name);
linked_list* find(const linked_list* head, int index);
linked_list* get_last_node(linked_list* head);
int append_node(linked_list* head, int index, char* name);
int print_node(const linked_list* node);
#endif // _LINKED_LIST_H_
linked_list.c
/*--------------------------------------------------
linked list methods.
--------------------------------------------------*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "../include/linked_list.h"
linked_list* create_node() {
return (linked_list*)malloc(sizeof(linked_list));
}
linked_list* find(const linked_list* head, int index) {
for (linked_list* p = head->next; p != head; p = p->next) {
if (p->index == index)
{
return p;
}
}
}
int set_node(const linked_list* head, int index, char* name) {
linked_list* p1 = find(head, index);
strncpy(p1->name, name, MAX_SHORT_NAME);
return 1;
}
linked_list* get_last_node(linked_list* head)
{
linked_list* last_node = head;
for (linked_list* p = head->next; p != head; p = p->next)
last_node = p;
return last_node;
}
int append_node(linked_list* head, int index, char* name) {
linked_list* last_node = get_last_node(head);
linked_list* p_new = create_node();
last_node->next = p_new;
p_new->next = head;
p_new->index = index;
strncpy(p_new->name, name, sizeof(name));
return 1;
}
int print_node(const linked_list* node) {
return printf("[%s %s] [%x] next-> [%x] index:%d name:%s\n", __DATE__, __TIME__, node, node->next, node->index, node->name);
}
本文介绍了如何在C语言中定义一个链表数据结构,包括创建节点、设置节点值、遍历链表以及对代码进行优化的方法。通过示例代码展示了如何构建一个环形链表,并提供了完整的源代码文件。
1760

被折叠的 条评论
为什么被折叠?



