双向循环链表的实现
带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都
是带头双向循环链表。另外这个结构虽然结构复杂,但是实现起来非常的简单,比单链表更有优势
以下便是实现带头双向循环链表需要的实现的一些功能
#include<assert.h>
#include<stdlib.h>
#include<stdio.h>
#include<stdbool.h>
typedef int DLNtype;
typedef struct DListNode
{
DLNtype data;
struct DListNode* next;//后节点
struct DListNode* prev;//前节点
}DListnode;
//初始化双向循环链表
DListnode* LTInit();
//头插
void LTpushfront(DListnode*phead,DLNtype x);
//头删
void LTpopfront(DListnode* phead);
//尾插
void LTpushback(DListnode* phead, DLNtype x);
//尾删
void LTpopback(DListnode* phead);
//新节点的创建
DListnode* Buylistnode(DLNtype x);
//双向循环链表的打印
void LTprint(DListnode* phead);
//寻找pos位置节点
DListnode* LTfind(DListnode*phead,DLNtype x);
//中间插入
void LTInsert(DListnode*phead,DLNtype x);
//中间删除
void LTErase(DListnode* phead);
//判断空链表
bool SLempty(DListnode* phead);
函数块的实现
#include"slist.h"
DListnode* Buylistnode(DLNtype x)
{
DListnode* newnode = (DListnode*)malloc(sizeof(DListnode));
if (newnode == NULL)
{
perror("malloc fail");
return;
}
newnode->data = x;
newnode->next = NULL;
newnode->prev = NULL;
return newnode;
}
DListnode* LTInit()
{
DListnode* phead = (DListnode*)malloc(sizeof(DListnode));
if (phead == NULL)
{
perror("malloc fail");
return;
}
phead->next = phead;
phead->prev = phead;
return phead;
}
void LTpushback(DListnode* phead, DLNtype x)
{
assert(phead);
DListnode* newnode = Buylistnode(x);
DListnode* tail = phead->prev;
tail->next = newnode;
newnode->prev = tail;
newnode->next = phead;
phead->prev = newnode;
}
void LTpopfront(DListnode* phead)
{
assert(phead);
assert(!SLempty(phead));
DListnode* nextnode = phead->next->next;
free(phead->next);
phead->next = nextnode;
nextnode->prev = phead;
}
void LTprint(DListnode* phead)
{
assert(phead);
printf("<-head->");
DListnode* cur = phead->next;
while (cur != phead)
{
printf("<-%d->", cur->data);
cur = cur->next;
}
printf("\n");
}
void LTpushfront(DListnode* phead, DLNtype x)
{
assert(phead);
DListnode* newnode = Buylistnode(x);
newnode->next = phead->next;
phead->next->prev = newnode;
phead->next = newnode;
newnode->prev = phead;
}
void LTpopback(DListnode* phead)
{
assert(phead);
assert(!SLempty(phead));
DListnode* tail = phead->prev;
DListnode* prevtail = tail->prev;
free(tail);
prevtail->next = phead;
phead->prev = prevtail;
}
DListnode* LTfind(DListnode* phead, DLNtype x)
{
assert(phead);
DListnode* cur = phead->next;
while (cur != phead)
{
if (cur->data == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
void LTInsert(DListnode* pos, DLNtype x)
{
assert(pos);
DListnode* prevnode = pos->prev;
DListnode* newnode = Buylistnode(x);
prevnode->next = newnode;
newnode->prev = prevnode;
newnode->next = pos;
pos->prev = newnode;
}
void LTErase(DListnode* pos)
{
assert(pos);
DListnode* prevnode = pos->prev;
DListnode* nextnode = pos->next;
free(pos);
prevnode->next = nextnode;
nextnode->prev = prevnode;
}
bool SLempty(DListnode* phead)
{
assert(phead);
return phead->next == phead;
}
主函数测试部分
#include"slist.h"
int main() {
DListnode* plist = LTInit();
LTpushback(plist, 1);
LTpushback(plist, 2);
LTpushback(plist, 3);
LTpushback(plist, 4);
LTpushfront(plist, 1);
LTpushfront(plist, 2);
LTpushfront(plist, 3);
LTpushfront(plist, 4);// 4 3 2 1 1 2 3 4
LTpopback(plist);
LTpopback(plist); // 4 3 2 1 1 2
LTpopfront(plist);
LTpopfront(plist);
LTprint(plist); // 2 1 1 2
DListnode* pos1 = LTfind(plist, 1);
LTInsert(pos1, 3);
DListnode* pos2 = LTfind(plist, 2);
LTErase(pos2);
LTprint(plist);
return 0;
}
运行结果示例
以上就是双向循环链表的代码基本实现