双向带头循环链表是带有头节点的循环链表,其相较于单链表结构更加复杂,但实现各个功能更加简单。
1、链表的初始化
ListNode* ListInit()
{
ListNode* newnode = BuyListNode(0);
newnode->next = newnode->prev = newnode;
return newnode;
}
2、链表的尾插
void ListPushBack(ListNode* phead, LTDataType x)
{
assert(phead);
ListNode* newNode = BuyListNode(x);
ListNode* tail = phead->prev;
tail->next = newNode;
newNode->prev = tail;
newNode->next = phead;
phead->prev = newNode;
}
3、链表的头插
void ListPushFront(ListNode* phead, LTDataType x)
{
assert(phead);
ListNode* newNode = BuyListNode(x);
ListNode* next = phead->next;
phead->next = newNode;
newNode->next = next;
newNode->prev = phead;
next->prev = newNode;
}
4、链表的尾删
void ListPopBack(ListNode* phead)
{
assert(phead);
assert(phead->next != phead);//链表为空,只有一个哨兵位
ListNode* tail = phead->prev;
ListNode* next = tail->prev;
next->next = phead;
phead->prev = next;
free(tail);
tail = NULL;
}
5、链表的头删
void ListPopFront(ListNode* phead)
{
assert(phead);
assert(phead->next != phead);//链表为空,只有一个哨兵位
ListNode* next = phead->next;
ListNode* nextnext = next->next;
phead->next = nextnext;
next->prev = phead;
free(next);
next = NULL;
}
6、链表任意位置的插入
void ListInsert(ListNode* pos, LTDataType x)
{
assert(pos);
ListNode* newNode = BuyListNode(x);
newNode->next = pos->next;
newNode->prev = pos;
pos->next->prev = newNode;
pos->next = newNode;
}
7、链表任意位置的删除
void ListErase(ListNode* pos) {
assert(pos);
pos->next->prev = pos->prev;
pos->prev->next = pos->next;
free(pos);
pos = NULL;
}
8、查找链表中的值
ListNode* ListFind(ListNode* phead, LTDataType x)
{
assert(phead);
ListNode* cur = phead->next;
while (cur != phead)
{
if (cur->data == x)
return cur;
cur = cur->next;
}
return NULL;
}
9、链表的销毁
void LTDesTroy(ListNode* phead) {
//哨兵位不能为空
assert(phead);
ListNode* pcur = phead->next;
while (pcur != phead)
{
ListNode* next = pcur->next;
free(pcur);
pcur = next;
}
//链表中只有一个哨兵位
free(phead);
phead = NULL;
}