文章目录
?链表功能动画演示
?逻辑实现text.c
?头文件List.h
?函数实现List.c
??八大链表结构为何选择了它
C++的STL库选择的最终链表结构为双向循环带头链表
为什么选择了它呢,是因为它的结构更优,虽然形式看似复杂,但的它便利性相比其他链表好得多
C++标准库中把list设计为带头节点的双向循环链表是很合理的,不信你往后看它的操作实现过程相比于单链表来说有多简单,当然你也可以用其他的六种结果来对比,结果一定是双向循环带头链表更胜一筹
认识八种链表的类型
- 单向带头非循环链表
- 单向不带头循环链表
- 单向不带头非循环链表
- 双向带头循环链表
- 双向带头非循环链表
- 双向不带头循环链表
- 双向不带头非循环链表
- 双向循环带头链表
一些链表图示
常用的两类链表结构
我们在单链表的一系列操作中讲过单链表是在一些OJ题的常考题单链表只能单向循环链表
循环双向链表就是一个环形,可以逆时针走,可以顺时针走,而双向链表是一个链,只能双向遍历。
??初始化和打印
初始化
我们的双向循环链表采用的是带哨兵位的头结点,它的初始化为了避免要传二级指针,可以设置用返回值的函数带回地址
下面一张图再次带你认识带哨兵位的头结点和不带哨兵位的头结点区别
要注意双向循环带头链表的初始化跟单链表有所区别,双向循环链表是不会指向NULL的,它没有节点的时候是下面的这种形式>
其实就是自己的头和尾都指向自己,这才能体现它的循环结构
在初始的时候是需要创建新节点作为头结点的,而且后续的头插,尾插等等都需要创建新节点,为了避免重复操作,直接建立一个BuyListNode函数用来创建新节点
//创建新节点
LTNode* BuyListNode(LTDateType x)
{
LTNode* newNode = (LTNode*)malloc(sizeof(LTNode));
if (newNode == NULL)
{
exit(-1);
}
newNode->date = x;
newNode->next = NULL;
newNode->prev = NULL;
return newNode;
}
//初始化
LTNode* ListInit()
{
LTNode* phead = BuyListNode(0);
phead->prev = phead;
phead->next = phead;
return phead;
}
//用一个指针接收地址
LTNode* list = ListInit();
打印