双向:头的prior要指向链表最后一个
循环:最后结点的next要只向头
示意图如下:
双向循环链表结构体声明
typedef struct DCNode
{
int data;
struct DCNode *prior;
struct DCNode *next;
}DCNode, *DCLinklist;
(1)初始化
void InitLinklist(DCLinklist plist)
{
assert(plist != NULL);
if(plist == NULL)
return;
plist->next=plist->prior=plist; //既要保证双向,也要保证循环
}
(2)求链表长度
int ListLength(DCLinklist plist)
{
assert(plist != NULL);
if(plist == NULL)
return -1;
int count = 0;
DCLinklist p=plist->next;
while(p != plist) //头尾不重合
{
count++;
p=p->next;
}
return count;
}
(3)静态函数:申请结点空间(和双向链表类似)
static DCLinklist ApplyNode(DCLinklist next,DCLinklist prior, int data)
{
DCLinklist s=(DCNode *) malloc (sizeof(DCNode));
if(s == NULL)
{
return NULL;
}
s->data=data;
s->prior=prior;
s->next=next;
return s;
}
(4)得到某个结点,函数返回该结点
DCLinklist GetNode(DCLinklist plist, int pos) //(此时认为pos在0---length之间)
{
assert(plist != NULL);
if(plist == NULL)
return NULL;
if(pos < 0)
return NULL;
DCLinklist p=plist;
while( pos !=0 && p->next != plist)
{
p=p->next;
pos--;
}
if(pos == 0) //若找到结点则返回给结点
return p;
return NULL; //否则都返回空
}
(5)插入
void Insert(DCLinklist plist, int val, int pos)
{
assert(plist != NULL);
if(plist == NULL)
return;
DCLinklist p=GetNode(plist, pos); //确保4条线指向
if(p == NULL)
{
return;
}
DCLinklist s=ApplyNode(p->next,p,val);
if(s == NULL)
return;
p->next->prior=s;
p->next=s;
}
(6)头插
void InsertHead(DCLinklist plist, int val)
{
assert(plist != NULL);
if(plist == NULL)
return;
Insert(plist, val, 0);
}
(7)尾插
void InsertTail(DCLinklist plist, int val)
{
assert(plist != NULL);
if(plist == NULL)
return;
DCLinklist p=ApplyNode(plist, plist->prior, val);
if(p == NULL)
{
return;
}
plist->prior->next=p;
plist->prior=p;
}
(8)删除
void Delete(DCLinklist plist, int pos)
{
assert(plist != NULL);
if(plist == NULL)
return;
DCLinklist p=GetNode(plist, pos); //要删除的结点
p->prior->next=p->next;
p->next->prior=p->prior;
free(p);
}
(9)头删
void DeleteHead(DCLinklist plist)
{
assert(plist != NULL);
if(plist == NULL)
return;
Delete(plist, 1);
}
(10)尾删
void DeleteTail(DCLinklist plist)
{
assert(plist != NULL);
if(plist == NULL)
return;
DCLinklist p=plist->prior;//即最后一个结点
p->prior->next=plist;
p->next->prior=p->prior;
free(p);
}
(11)判空
int IsEmpty(DCLinklist plist)
{
assert(plist != NULL);
if(plist == NULL || plist->next ==plist)
return -1;
return 0;
}
(12)清空链表
void ClearEmpty(DCLinklist plist)
{
assert(plist != NULL);
if(plist == NULL)
return;
while(! IsEmpty(plist))
{
DeleteHead(plist);
}
}
(13)输出
void Show(DCLinklist plist)
{
assert(plist != NULL);
if(plist == NULL)
return;
DCLinklist p=plist->next;
while(p != plist)
{
printf("%d-->",p->data);
p=p->next;
}
printf("NULL\n");
}