双向循环链表(C语言)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wuxinrenping/article/details/80098311

一、seqlist.h

#ifndef __SEQLIST__

#define __SEQLIST__

typedef int DataType;
typedef struct DCLNode
{
struct DCLNode* _pNext;
struct DCLNode* _pPre;
DataType _data;
}Node, *PNode;

void DCLInit(PNode* ppHead);  //双向循环链表的初始化
void DCLPushBack(PNode pHead, DataType data);   //尾插
void DCLPopBack(PNode pHead);    //尾删
void DCLPushFront(PNode pHead, DataType data);    //头插
void DCLPopFront(PNode pHead);    //头删
void DCLInsert(PNode pos, DataType data);    //任意位置插入(包括头插和尾插)
void DCLErase(PNode pos);   //任意位置删除(包括头删和尾删)
void DCLDestroy(PNode* ppHead); //链表销毁
PNode DCLFind(PNode pHead, DataType data);   //链表查找

PNode DCLBuyNode(DataType data);   //创建节点
void DCLPrintList(PNode pHead);   //打印链表

#endif

二、seqlist.c

#include<stdio.h>
#include<malloc.h>
#include<assert.h>
#include"seqlist.h"

PNode DCLBuyNode(DataType data)
{
PNode pnewnode = (PNode) malloc(sizeof(Node));
assert(pnewnode);
pnewnode->_data = data;
pnewnode->_pNext = NULL;
pnewnode->_pPre = NULL;
}

void DCLInit(PNode* ppHead)
{
PNode pnewnode = DCLBuyNode(0);
*ppHead = pnewnode;
(*ppHead)->_pNext = *ppHead;
(*ppHead)->_pPre = *ppHead;
}


void DCLPushBack(PNode pHead, DataType data)
{
assert(pHead);
PNode pnewnode = DCLBuyNode(data);
PNode ptail = NULL;
ptail = pHead->_pPre;
ptail->_pNext = pnewnode;
pnewnode->_pPre = ptail;
pHead->_pPre = pnewnode;
pnewnode->_pNext = pHead;
}

void DCLPopBack(PNode pHead)
{
assert(pHead);
if(pHead->_pNext == pHead)
{
return;
}
PNode pretail = pHead->_pPre->_pPre;
free(pHead->_pPre);
pHead->_pPre = pretail;
pretail->_pNext = pHead;
}

void DCLPushFront(PNode pHead, DataType data)
{
assert(pHead);
PNode pnewnode = DCLBuyNode(data);
PNode ptail = NULL;
ptail = pHead->_pNext;
ptail->_pPre = pnewnode;
pHead->_pNext = pnewnode;
pnewnode->_pPre = pHead;
pnewnode->_pNext = ptail;
}

void DCLPopFront(PNode pHead)
{
assert(pHead);
if (pHead->_pNext == pHead)
{
return;
}
PNode pdel = pHead->_pNext;
pHead->_pNext = pdel->_pNext;
pdel->_pNext->_pPre = pHead;
free(pdel);
}

void DCLInsert(PNode pos, DataType data)
{
PNode pnewnode = DCLBuyNode(data);
pos->_pPre->_pNext = pnewnode;
pnewnode->_pPre = pos->_pPre;
pos->_pPre = pnewnode;
pnewnode->_pNext = pos;
}

void DCLErase(PNode pos)
{
pos->_pPre->_pNext = pos->_pNext;
pos->_pNext->_pPre = pos->_pPre;
free(pos);
}

void DCLDestroy(PNode* ppHead)
{
assert(ppHead);
PNode pcur = NULL;
PNode pre = NULL;
pcur = (*ppHead)->_pNext;
while (pcur!=*ppHead)
{
pre = pcur;
pcur = pcur->_pNext;
free(pre);
}
free(pcur);
*ppHead = NULL;
}

PNode DCLFind(PNode pHead, DataType data)
{
assert(pHead);
PNode pcur = NULL;
pcur = pHead->_pNext;
while (pcur != pHead)
{
if (pcur->_data == data)
{
return pcur;
}
pcur = pcur->_pNext;
}
return NULL;
}

void DCLPrintList(PNode pHead)
{
assert(pHead);
PNode pcur = NULL;
pcur = pHead->_pNext;
while (pcur != pHead)
{
printf("%d-->", pcur->_data);
pcur = pcur->_pNext;
}
printf("NULL");
}

void test()
{
PNode phead;
PNode pos;
DCLInit(&phead);
DCLPushBack(phead, 3);
DCLPushBack(phead, 4);
DCLPushBack(phead, 5);
DCLPushBack(phead, 6);
DCLPushBack(phead, 7);
DCLPrintList(phead);

DCLPopBack(phead);
DCLPopBack(phead);
DCLPrintList(phead);

DCLPushFront(phead, 2);
DCLPushFront(phead, 1);
DCLPrintList(phead);

DCLPopFront(phead);
DCLPopFront(phead);
DCLPrintList(phead);

pos = DCLFind(phead, 4);
DCLInsert(pos, 10);
DCLPrintList(phead);

DCLErase(pos);
DCLPrintList(phead);

DCLDestroy(&phead);

}

三、test.c

#include<stdio.h>
#include"seqlist.h"

int main()
{
test();
system("pause");
return 0;

}

      其实对于双向循环链表给大家的建议是多画图,搞懂每个结点的前驱和后继到底是什么?还有就是尾节点的后继是头结点,头结点的前驱是尾节点。

猜你喜欢

转载自blog.csdn.net/wuxinrenping/article/details/80098311