既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
前言
🌏一、双链表概念
🍤第一个结点属于多开辟的空间,为了方便头插头删,后续结点为真正的链表内容。
内容:
🍤一个指向前面结点的指针
🍤一个存储数据的空间
🍤一个指向后面结点的指针
🌏二、代码实现
🍯1.双链表定义
🍤与链表不同的是,双链表结构更复杂,但其实实现起来比单链表简单,并且还有一个哨兵
//此双链表带哨兵位
typedef int typedefData;
typedef struct Double_linked_list {
typedefData Data; //数据
struct Double_linked_list* next;//下一个指针
struct Double_linked_list* prev;//上一个指针
}Double_linked_list;
🍯2.双链表初始化两种形式
🍤初始化时,我们要将哨兵位地址传过去,因为我们要修改哨兵位的值,将哨兵位值修改为0,两个指针都指向他自己
//初始化不带返回值
void InitializeNotReturn_Double_linked_list(Double_linked_list** pphead) {
assert(pphead);
*pphead = Application_Double_linked_list(0);
(*pphead)->next = *pphead;
(*pphead)->prev = *pphead;
}
🍤这里不用传送哨兵位的值,因为直接在,函数中创建一个哨兵,并且将值设为0,两个指针指向他自己,最后将这个地址返回
//初始化带返回值
Double_linked_list* InitializeReturn_Double_linked_list(void) {
Double_linked_list* phead = Application_Double_linked_list(0);
phead->next = phead;
phead->prev = phead;
return phead;
}
🍯3.双链表申请空间
🍤新的空间设为我们需要的值,将两个指针都置为空,返回新空间的地址
//申请一个空间
Double_linked_list* Application_Double_linked_list(typedefData x) {
Double_linked_list* newnode = (Double_linked_list*)malloc(sizeof(Double_linked_list));
if (newnode == NULL) {
printf("fail malloc:%s\n", strerror(errno));
exit(-1);
}
newnode->next = NULL;
newnode->prev = NULL;
newnode->Data = x;
return newnode;
}
🍯4.双链表尾插
🍤1.创建新结点存储数据
🍤2.原尾结点与新结点进行相互链接
🍤3.新结点与头结点相互链接
//尾插
void PushBack_Double_linked_list(Double_linked_list* phead, typedefData x) {
assert(phead);
Double_linked_list* newnode = Application_Double_linked_list(x);
Double_linked_list* tail = phead->prev;
tail->next = newnode;
newnode->prev = tail;
phead->prev = newnode;
newnode->next = phead;
}
🍯5.双链表尾删
🍤1.找到尾结点和倒数第二个结点
🍤2.释放尾结点
🍤3.头结点和倒数第二个结点链接
void PopBack_Double_linked_list(Double_linked_list* phead) {
assert(phead);
Double_linked_list* tail = phead->prev;
Double_linked_list* tailprev = tail->prev;
phead->prev = tailprev;
tailprev->next = phead;
free(tail);
tail = NULL;
}
🍯6.双链表打印
🍤用一个cur节点指针来走,走到head的位置就停下来
void Print_Double_linked_list(Double_linked_list* phead) {
assert(phead);
Double_linked_list* cur = phead->next;
printf("Head ");
while (cur != phead) {
printf("<-> %d ", cur->Data);
cur = cur->next;
}
printf("<-> Head\n");
}
🍯7.双链表头插
🍤1.创建新结点存储数据
🍤2.新结点与头结点后的第一个结点链接
🍤3.第三步,新结点与头结点链接
void PushFront_Double_linked_list(Double_linked_list* phead, typedefData x) {
assert(phead);
Double_linked_list* newnode = Application_Double_linked_list(x);
Double_linked_list* cur = phead->next;
Double_linked_list* curnext = cur->next;
cur->next = newnode;
newnode->prev = cur;
curnext->prev = newnode;
newnode->next = curnext;
}
🍯8.双链表头删
🍤1.头结点与头删结点后的结点链接
🍤2.释放头删结点
void PopFront_Double_linked_list(Double_linked_list* phead) {
assert(phead);
Double_linked_list* cur = phead->next;
Double_linked_list* curnext = cur->next;
phead->next = curnext;
curnext->prev = phead;
free(cur);
cur = NULL;
}
🍯9.双链表查找
🍤直接遍历
Double_linked_list* Find_Double_linked_list(Double_linked_list* phead, typedefData x) {
assert(phead);
Double_linked_list* cur = phead->next;
while (cur != phead) {
if (cur->Data == x) {
return cur;
}
cur = cur->next;
}
return NULL;
}
🍯10.中间插入及头插和尾插优化
🍍中间插入
🍤任意位置前插入是在给定的
pos
结点之后插入
void Insert_Double_linked_list(Double_linked_list* pos, typedefData x) {
assert(pos);
Double_linked_list* newnode = Application_Double_linked_list(x);
Double_linked_list* next = pos->next;
newnode->next = next;
next->prev = newnode;
pos->next = newnode;
newnode->prev = pos;
}
🍍头插优化
🍤直接传头的下一个节点


**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.youkuaiyun.com/topics/618668825)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
🍍头插优化
>
> 🍤直接传头的下一个节点
>
>
>
[外链图片转存中…(img-z3UMkD2E-1715725780216)]
[外链图片转存中…(img-WZYc03rM-1715725780216)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!