带头双向循环链表:在链表中结构最复杂,单独存储数据基本都是用这个结构,这个结构虽然最复杂,但这种复杂也为我们带来了很多优势,让使用者可以很方便的访问前驱和后继节点。
如下图:每个节点由前驱指针,后继指针和数据组成。
头文件
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int LTDataType;
typedef struct ListNode
{
struct ListNode* prev;
LTDataType data;
struct ListNode* next;
}ListNode;
//创建新节点
ListNode* BuyListNode(LTDataType x);
//初始化链表
ListNode* LTInit();
//打印链表
void LTPrint(ListNode* phead);
//尾部插入
void LTPushBank(ListNode* phead,LTDataType x);
//头部插入
void LTPushFront(ListNode* phead, LTDataType x);
//尾部删除
void LTPopBank(ListNode* phead);
//头部删除
void LTPopFront(ListNode* phead);
//查找节点
ListNode* LTFind(ListNode* phead,LTDataType x);
//删除节点
void ListErase(ListNode* pos);
//插入数据
void ListInsert(ListNode* pos, LTDataType x);
//删除链表
void LTDestroy(ListNode* phead);
函数的实现
创建新节点及初始化:
ListNode* BuyListNode(LTDataType x)
{
ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
newnode->data = x;
newnode->next = NULL;
newnode->prev = NULL;
return newnode;
}
ListNode* LTInit()
{
ListNode* phead = BuyListNode(-1);
phead->next = phead;
phead->prev = phead;
}
尾插:
void LTPushBank(ListNode* phead, LTDataType x)
{
assert(phead);
//ListInsert(phead, x);
ListNode* newnode = BuyListNode(x);
ListNode* prev = phead->prev;
newnode->prev = prev;
newnode->next = phead;
prev->next = newnode;
phead->prev = newnode;
}
头插:
void LTPushFront(ListNode* phead, LTDataType x)
{
assert(phead);
//ListInsert(phead->next, x);
ListNode* newnode = BuyListNode(x);
ListNode* next = phead->next;
phead->next = newnode;
newnode->prev = phead;
newnode->next = next;
next->prev = newnode;
}
尾删:
void LTPopBank(ListNode* phead)
{
assert(phead);
assert(!IsEmpty(phead));
//ListErase(phead->prev);
ListNode* prev = phead->prev->prev;
ListNode* cur = phead->prev;
prev->next = phead;
phead->prev = prev;
free(cur);
}
头删:
void LTPopFront(ListNode* phead)
{
assert(phead);
assert(!IsEmpty(phead));
//ListErase(phead->next);
ListNode* next = phead->next->next;
ListNode* cur = phead->next;
phead->next = next;
next->prev = phead;
free(cur);
}
查找节点:
ListNode* LTFind(ListNode* phead,LTDataType x)
{
assert(phead);
ListNode* cur = phead->next;
while (cur != phead)
{
if (cur->data == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
删除节点:
void ListErase(ListNode* pos)
{
assert(pos);
ListNode* prev = pos->prev;
ListNode* next = pos->next;
prev->next = next;
next->prev = prev;
free(pos);
}
在Pos节点之前插入数据:
void ListInsert(ListNode* pos, LTDataType x)
{
ListNode* prev = pos->prev;
ListNode* newnode = BuyListNode(x);
prev->next = newnode;
newnode->prev = prev;
newnode->next = pos;
pos->prev = newnode;
}
打印链表:
void LTPrint(ListNode* phead)
{
assert(phead);
ListNode* cur = phead->next;
while (cur != phead)
{
printf("%d<==>", cur->data);
cur = cur->next;
}
}
删除链表:
void LTDestroy(ListNode* phead)
{
ListNode* cur = phead->next;
ListNode* next = cur->next;
while (cur != phead)
{
next = cur->next;
free(cur);
cur = next;
}
}