目录
1. 双向循环链表(带哨兵位)
双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
2.1 双链表结构
注意事项:
1.定义两个指针分别指向头和尾
typedef int LTDataType;
typedef struct ListNode
{
struct ListNode* prev;
struct ListNode* next;
LTDataType data;
}ListNode;
2.2 创建双链表结点
注意事项:
1.malloc记得判空
2.初始化newnode内的指针
ListNode* ListCreate(LTDataType x)//创建双链表结点
{
ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
if (newnode == NULL)
{
perror("malloc:fail");
exit(-1);
}
newnode->next = NULL;
newnode->prev = NULL;
newnode->data = x;
return newnode;
}
2.3 初始化双链表
注意事项:
1.让头结点的next和prev指向自己
ListNode* ListInit()
{
ListNode* pphead = ListCreate(-2);
pphead->next = pphead;
pphead->prev = pphead;
return pphead;
}
2.4 尾插
注意事项:
1.头结点的prev就是尾,找到尾后修改尾的next,修改newnode的prev和next,和无效头结点phead的prev (看图写代码)
void ListPushBack(ListNode* pHead, LTDataType x)//尾插
{
assert(pHead);
ListNode* newnode = ListCreate(x);
ListNode* tail = pHead->prev;//找到尾
//双链表的链接
tail->next = newnode;
newnode->prev = tail;
pHead->prev = newnode;
newnode->next = pHead;
}
2.5 尾删
注意事项:
1.注意控制边界,不要删除无效头结点
2.记录尾删结点和尾删节点的前一个,这样顺序便不重要
void ListPopBack(ListNode* pHead)//双链表尾删
{
assert(pHead);
assert(pHead->next != pHead);
ListNode* del = pHead->prev;
ListNode* prevdel = del->