免费的网站空间申请,做网站备案与不备案的区别,wordpress 404自定义,宣传片制作公司的知名品牌C语言#xff0c;链表C实现单向链表深入理解Linux内核链表跟单链表不同#xff0c;双链表的节点包含两个指针#xff0c;一个指针指向上一个元素#xff0c;一个指针指向下一个元素。▌如下图学习数据结构的时候#xff0c;要像认识一个人一样#xff0c;要了解这个人有什… C语言链表C实现单向链表深入理解Linux内核链表跟单链表不同双链表的节点包含两个指针一个指针指向上一个元素一个指针指向下一个元素。▌如下图学习数据结构的时候要像认识一个人一样要了解这个人有什么特点比如喜欢打球喜欢喝酒之类的。学习数据结构也是一样要了解数据结构的特点。我们要学习双链表需要搞明白链表这几个特点创建链表往链表插入数据删除链表中的某个数据删除整个链表查找链表反转链表▌先看看如何创建一个链表创建一个链表无非就是搞定链表头没有头的链表就是死链表有头就表示这个链表是存在的。当然了可能会存在循环链表只有位置没有固定的头指针。创建一个pHead并且以后pHead头指针保持不动就表示我们创建好了一个链表头指针。typedef struct Node{struct Node *prev;struct Node *next;int elements;
}pNode;pNode * CreateHead(void)
{pNode *head NULL;head (pNode *)malloc(sizeof(struct Node));head-next NULL;head-prev NULL;return head;
}
▌插入元素插入元素的方式有多种可以头插可以尾插也可以任意插我只写了简单的插入方式-尾插。int InsertElement(pNode *head,int element)
{if(head NULL){PRINTK_LINK(Head NULL\n);return (-1);}pNode * pTemp head;while(pTemp-next ! NULL){pTemp pTemp-next;}pNode * pElement (pNode *)malloc(sizeof(struct Node));pElement-elements element;pTemp-next pElement;pElement-prev pTemp;PRINTK_LINK(Element:%d\n,element);return (0);
}
▌遍历一个链表遍历链表是常规的操作但是遍历链表的方法有很多种可以从头开始遍历可以从尾部开始在涉及二分查找的时候可以从中间某个位置开始遍历。虽然方法很多但是我只写了一种方法就是从头开始遍历链表因为是最简单的。int TraverseLink(pNode *head)
{if(head NULL){PRINTK_LINK(Head NULL\n);return (-1);}pNode * pTemp head;while(pTemp-next ! NULL){pTemp pTemp-next;PRINTK_LINK(Element:%d\n,pTemp-elements);}return (0);
}
▌删除链表删除整个链表是把链表的每个元素都删除并且把头也删除并且把头指针指向NULL。如果需要找到链表中的某个元素并删除就需要先找到链表中的元素删除掉并且把前后的两个元素连在一起。int DeleteLink(pNode *head)
{if(head NULL){PRINTK_LINK(Head NULL\n);return (-1);}pNode * pTemp head;while(pTemp-next ! NULL){pTemp pTemp-next;}while(pTemp ! NULL){free(pTemp); pTemp NULL;pTemp pTemp-prev;}return (0);
}
▌完整代码#include stdio.h
#include string.h
#include stdlib.h#define LOG_TAG [LINK]: %s() line: %d
#define PRINTK_LINK(fmt, args...) printf(LOG_TAG fmt, __FUNCTION__, __LINE__, ##args)typedef struct Node{struct Node *prev;struct Node *next;int elements;
}pNode;pNode * CreateHead(void)
{pNode *head NULL;head (pNode *)malloc(sizeof(struct Node));head-next NULL;head-prev NULL;return head;
}int InsertElement(pNode *head,int element)
{if(head NULL){PRINTK_LINK(Head NULL\n);return (-1);}pNode * pTemp head;while(pTemp-next ! NULL){pTemp pTemp-next;}pNode * pElement (pNode *)malloc(sizeof(struct Node));pElement-elements element;pTemp-next pElement;pElement-prev pTemp;PRINTK_LINK(Element:%d\n,element);return (0);
}int TraverseLink(pNode *head)
{if(head NULL){PRINTK_LINK(Head NULL\n);return (-1);}pNode * pTemp head;while(pTemp-next ! NULL){pTemp pTemp-next;PRINTK_LINK(Element:%d\n,pTemp-elements);}return (0);
}int DeleteLink(pNode *head)
{if(head NULL){PRINTK_LINK(Head NULL\n);return (-1);}pNode * pTemp head;while(pTemp-next ! NULL){pTemp pTemp-next;}while(pTemp ! NULL){free(pTemp);pTemp pTemp-prev;}return (0);
}int main()
{pNode * pHead CreateHead();InsertElement(pHead,13);InsertElement(pHead,8);InsertElement(pHead,0);InsertElement(pHead,4);InsertElement(pHead,485);InsertElement(pHead,94);TraverseLink(pHead);DeleteLink(pHead);return 0;
}
▌程序输出ubuntu1804:~/c$ gcc shuanglianbiao.c ./a.out
[LINK]: InsertElement() line: 40 Element:13
[LINK]: InsertElement() line: 40 Element:8
[LINK]: InsertElement() line: 40 Element:0
[LINK]: InsertElement() line: 40 Element:4
[LINK]: InsertElement() line: 40 Element:485
[LINK]: InsertElement() line: 40 Element:94
[LINK]: TraverseLink() line: 56 Element:13
[LINK]: TraverseLink() line: 56 Element:8
[LINK]: TraverseLink() line: 56 Element:0
[LINK]: TraverseLink() line: 56 Element:4
[LINK]: TraverseLink() line: 56 Element:485
[LINK]: TraverseLink() line: 56 Element:94
▌总结我上面的代码只设计了链表头如果设计链表尾部指针应用会更加灵活。相比于单链表双链表的操作会更加灵活当然每一个节点都需要新增一个指向于上一个位置的指针。双链表还可以把头尾连接起来变成一个环形队列。链表相对于数组来说插入和删除数据非常快因为不需要移动数据只需要改变指针的指向。双链表内存利用率高如果是内存紧张的硬件设备使用链表操作可以节省内存。相对于数组链表可以做到按需分配内存。链表是一种基础的数据结构建议做到自己能写出一个链表不要求十全十美我曾经面试遇到让我手撸一个栈。相对于那些C语言基础写代码更能彰显程序员的技术。推荐阅读专辑|Linux文章汇总专辑|程序人生专辑|C语言我的知识小密圈关注公众号后台回复「1024」获取学习资料网盘链接。欢迎点赞关注转发在看您的每一次鼓励我都将铭记于心~