双向循环链表:
循环链表是一种链式存储结构,它的最后一个结点指向头结点,形成一个环。因此,从循环链表中的任何一个结点出发都能找到任何其他结点。循环链表的操作和单链表的操作基本一致,差别仅仅在于算法中的循环条件有所不同。
实现代码:
在代码实现过程需要考虑很多特殊情况,
//创建双向循环链表。这里是创建了一个首元节点。所以不用考虑首元节点的问题。简化问题的复杂读。
Status createCycleLinkList(LinkList *L) {
*L = (LinkList)malloc(sizeof(Node));
if(NULL== *L) {
returnERROR;
}
(*L)->next= *L;
(*L)->precr= *L;
LinkListp = (*L);
for(inti=0; i<10; i++) {
LinkListtemp = (LinkList)malloc(sizeof(Node));
temp->data = i;
p->next=temp;
temp->precr= p;
temp->next = (*L);
p->precr= temp;
p = p->next;
}
returnOK;
}
插入节点:插入节点时需要注意的是:先连接当前的后驱和需要连接的位置的前驱,然后在连接当前节点的前驱,如果顺序反了,容易出现问题。
StatuslinkListInsertData(LinkList*L,intindex ,Enpteye) {
//1. 创建指针p,指向双向链表头
LinkList p = (*L);
if(NULL== p) {
returnERROR;
}
inti =1;
//2.双向循环链表为空,则返回error
if(*L ==NULL)returnERROR;
//3.找到插入前一个位置上的结点p
while(i < index && p->next!= *L) {
p = p->next;
i++;
}
//4.如果i>index 则返回error
if(i > index) returnERROR;
//5.创建新结点temp
LinkListtemp = (LinkList)malloc(sizeof(Node));
//6.temp 结点为空,则返回error
if(temp ==NULL)returnERROR;
//7.将生成的新结点temp数据域赋值e.
temp->data= e;
//8.将结点temp 的前驱结点为p;
temp->precr= p;
//9.temp的后继结点指向p->next;
temp->next= p->next;
//10.p的后继结点为新结点temp;
p->next= temp;
//如果temp 结点不是最后一个结点
if(*L != temp->next) {
//11.temp节点的下一个结点的前驱为temp 结点
temp->next->precr= temp;
}else{
(*L)->precr= temp;
}
returnOK;
}