双向循环链表的结构
由于单链表只能单向访问,在插入删除时有时需要寻找尾结点比较麻烦,在此基础上设置了双向循环链表,头尾互相指定。
typedef int DlistDataType;
typedef struct DListNode
{
int data;
struct DListNode* next;
struct DListNode* prev;
}SDListNode;
接口函数
(此处展示的是带哨兵位的链表,在main函数中,SDListNode*plist=NULL;,plist仅仅只是用来存放头结点的地址,往后的一切操作都是在这个头结点之后去进行插入删除,并不会改变plist所存储的值,自然不用传&plist,直接plist即可。)
//链表内容初始化
SDListNode* SDListInit();
//尾插
void SDListNodePushBack(SDListNode* head, DlistDataType x);
//打印
void SDListNodePrint(SDListNode* head);
//尾删
void SDListNodePopBack(SDListNode* head);
//头插
void SDListNodePushFront(SDListNode* head, DlistDataType x);
//头删
void SDListNodePopFront(SDListNode* head);
//寻找某一个元素
SDListNode* SDListFind(SDListNode* head,int pos);
//指定位置插入
void SDListNodeInsert(SDListNode* pos, DlistDataType x);
//指定位置删除
void SDListNodeEarse(SDListNode* pos);
//开辟空间的销毁
void SDListNodeDestroy(SDListNode* head);
接口函数的实现
//创建头结点
SDListNode* SDListInit()
{
SDListNode* head = (SDListNode*)malloc(sizeof(SDListNode));
head->next = head;
head->prev = head;
return head;
}
SDListNode* BuySDListNode(DlistDataType x)
{
SDListNode* newnode = (SDListNode*)malloc(sizeof(SDListNode));
newnode->data = x;
newnode->next = NULL;
newnode->prev = NULL;
return newnode;
}
void SDListNodePushBack(SDListNode* head, DlistDataType x)
{
assert(head);
SDListNode* newnode = BuySDListNode(x);
SDListNode* tail = head->prev;
tail->next = newnode;
newnode->prev = tail;
head->prev = newnode;
newnode->next = head;
}
void SDListNodePrint(SDListNode* head)
{
SDListNode* print = head->next;
while (print != head)
{
printf("%d ", print->data);
print = print->next;
}
printf("\n");
}
void SDListNodePopBack(SDListNode* head)
{
assert(head);
assert(head->next !=head);
SDListNode* tail = head->prev;
SDListNode* prev = tail->prev;
prev->next = head;
head->prev = prev;
free(tail);
}
//此处头插,是指在哨兵位后的第一个节点出插入,而不是在哨兵位处插入
void SDListNodePushFront(SDListNode* head, DlistDataType x)
{
SDListNode* newnode = BuySDListNode(x);
SDListNode* next = head->next;
head->next = newnode;
newnode->prev = head;
newnode->next = next;
next->prev = newnode;
}
void SDListNodePopFront(SDListNode* head)
{
assert(head);
assert(head->next != head);
SDListNode* cur = head->next;
SDListNode* next = cur->next;
head->next = next;
next->prev = head;
free(cur);
}
SDListNode* SDListFind(SDListNode* head, int pos)
{
SDListNode* cur = head->next;
while (cur != head)
{
if (cur->data == pos)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
//在指定位置之前插入
void SDListNodeInsert(SDListNode* pos, DlistDataType x)
{
SDListNode* newnode = BuySDListNode(x);
SDListNode* prev = pos->prev;
prev->next = newnode;
newnode->prev = prev;
newnode->next = pos;
pos->prev = newnode;
}
void SDListNodeEarse(SDListNode* pos)
{
SDListNode* posPrev = pos->prev;
SDListNode* posNext = pos->next;
posPrev->next = posNext;
posNext->prev = posPrev;
free(pos);
}
//最后在text.c中调用这个函数后,还应写:head=NULL;才算把这个链表销毁
void SDListNodeDestroy(SDListNode* head)
{
SDListNode* cur = head->next;
while (cur != head)
{
SDListNode* next = cur->next;
free(cur);
cur = next;
}
}