赞
踩
链表是C语言中比较常用的一种数据结构,相对与上几篇文章的队列结构来说,链表是在一种物理存储单元上非连续、非顺序的存储结构。链表中的每个节点都是通过链表中的指针链接次序实现的;一般来说每个节点都会包含以下两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
链表又会分成很多个类型:单线链表,单向循环链表,双向链表,双向循环链表等;
这篇文章我们主要聊聊单向链表,单向链表又分为以下两种类型:
链表的数据定义
typedef struct {
uint8_t id;
} USER_DATA_T;
typedef struct list{
struct list *next;
USER_DATA_T data;
} LIST_T;
LIST_T *head_list = NULL; //链表头节点指针
链表的创建
// 创建链表
int list_creat(void)
{
if (NULL == head_list) {
head_list = (LIST_T *)malloc(sizeof(LIST_T));
if (NULL == head_list) {
return -1;
}
head_list->next = NULL;
}
return 0;
}
链表的插入:头插和尾插
//链表的头插,在头节点后面插入数据 int list_inset_head(USER_DATA_T *data) { if (NULL == head_list) { if (list_creat() != 0) { return -1; } } LIST_T *p_node = (LIST_T *)malloc(sizeof(LIST_T)); memset(p_node, 0, sizeof(LIST_T)); memcpy(&p_node->data, data, sizeof(USER_DATA_T)); p_node->next = head_list->next; head_list->next = (struct list *)p_node; return 0; } //链表的尾插,在最后节点插入数据 int list_inset_tail(USER_DATA_T *data) { if (NULL == head_list) { if (list_creat() != 0) { return -1; } } //创建节点数据 LIST_T *p_node = (LIST_T *)malloc(sizeof(LIST_T)); memset(p_node, 0, sizeof(LIST_T)); memcpy(&p_node->data, data, sizeof(USER_DATA_T)); p_node->next = NULL; LIST_T *p_list = head_list; while (p_list) { if (p_list->next) { p_list = (LIST_T *)p_list->next; continue; } p_list->next = (struct list *)p_node; return 0; } }
链表的删除:根据数据内容或者节点序号
// 根据数据内容删除节点 void list_node_del_by_data(USER_DATA_T *data) { if (NULL == head_list) { return; } LIST_T *p_list = (LIST_T *)head_list; LIST_T *q = NULL; while (p_list->next) { if (0 == memcmp(data, &p_list->next->data, sizeof(USER_DATA_T))) { q = (LIST_T *)p_list->next; p_list->next = q->next; free(q); q = NULL; } p_list = (LIST_T *)p_list->next; } } // 根据节点编号删除节点:头节点为0,数据节点从1开始 void list_node_del_by_index(uint8_t index) { if ((NULL == head_list) || (0 == index)) { return; } uint8_t cnt = 1; LIST_T *q = NULL; LIST_T *p_list = (LIST_T *)head_list; while (p_list) { if (cnt == index) { q = p_list->next; p_list->next = q->next; free(q); q = NULL; return; } p_list = (LIST_T *)p_list->next; cnt++; } }
链表的销毁
//链表销毁
int list_destory(void)
{
if (NULL == head_list) {
return -1;
}
LIST_T *p_list = NULL, *q = NULL;
for (p_list = head_list->next; p_list != NULL; p_list = q) {
q = p_list->next;
free(p_list);
}
free(head_list);
return 0;
}
链表的遍历
//遍历链表
void list_traverse(void)
{
if ((NULL == head_list) || (NULL == head_list->next)) {
return;
}
LIST_T *p_node = (LIST_T *)head_list->next;
while (p_node) {
printf("node data:%d\r\n", p_node->data);
p_node = (LIST_T *)p_node->next;
}
}
链表的创建
// 创建链表
int list_creat(USER_DATA_T *data)
{
if (NULL == head_list) {
head_list = (LIST_T *)malloc(sizeof(LIST_T));
if (NULL == head_list) {
return -1;
}
memcpy(&head_list->data, data, sizeof(USER_DATA_T));
head_list->next = NULL;
}
return 0;
}
链表的插入:头插和尾插
//链表的头插,在头节点前面插入数据 int list_inset_head(USER_DATA_T *data) { if (NULL == head_list) { return -1; } LIST_T *p_node = (LIST_T *)malloc(sizeof(LIST_T)); memset(p_node, 0, sizeof(LIST_T)); memcpy(&p_node->data, data, sizeof(USER_DATA_T)); p_node->next = head_list; head_list = p_node; return 0; } //链表的尾插,在最后节点插入数据 int list_inset_tail(USER_DATA_T *data) { if (NULL == head_list) { return -1; } //创建节点数据 LIST_T *p_node = (LIST_T *)malloc(sizeof(LIST_T)); memset(p_node, 0, sizeof(LIST_T)); memcpy(&p_node->data, data, sizeof(USER_DATA_T)); p_node->next = NULL; LIST_T *p_list = head_list; while (p_list) { if (p_list->next) { p_list = (LIST_T *)p_list->next; continue; } p_list->next = (struct list *)p_node; return 0; } }
链表节点的删除:根据数据或者节点序号删除
// 根据数据内容删除节点 void list_node_del_by_data(USER_DATA_T *data) { if (NULL == head_list) { return; } LIST_T *p_list = (LIST_T *)head_list; LIST_T *q = NULL; while (p_list) { if (0 == memcmp(data, &p_list->data, sizeof(USER_DATA_T))) { if (p_list == head_list) { q = head_list; head_list = head_list->next; free(q); q = NULL; p_list = head_list; } else { q->next = p_list->next; free(p_list); p_list = NULL; q = (LIST_T *)q->next; } continue; } q = p_list; p_list = (LIST_T *)p_list->next; } } // 根据节点编号删除节点:头节点为0 void list_node_del_by_index(uint8_t index) { if (NULL == head_list) { return; } uint8_t cnt = 0; LIST_T *q = NULL; LIST_T *p_list = (LIST_T *)head_list; while (p_list) { if (cnt == index) { if (0 == index) { q = head_list; head_list = head_list->next; free(q); q = NULL; } else { q->next = p_list->next; free(p_list); p_list = NULL; } return; } q = p_list; p_list = (LIST_T *)p_list->next; cnt++; } }
链表节点的查找
// 根据数据内容查找节点
LIST_T *list_node_find(USER_DATA_T *data)
{
if (NULL == head_list) {
return;
}
LIST_T *p_list = (LIST_T *)head_list;
while (p_list) {
if (0 == memcmp(data, &p_list->data, sizeof(USER_DATA_T))) {
return p_list;
}
p_list = (LIST_T *)p_list->next;
}
}
demo测试代码
int main(void) { USER_DATA_T data = {0}; list_creat(); data.id = 3; list_inset_head(&data); data.id = 2; list_inset_head(&data); data.id = 4; list_inset_tail(&data); data.id = 5; list_inset_tail(&data); data.id = 1; list_inset_head(&data); data.id = 3; list_inset_head(&data); data.id = 3; list_node_del_by_data(&data); list_node_del_by_index(3); list_traverse(); list_destory(); list_traverse(); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。