一,双向链表
单向链表的链式存储结构的节点中只有一个指向直接后继的指针域,由此从某个节点出发只能顺指针往后寻查其他节点。若要寻查节点的直接前驱,则需从表头指针出发。换句话说,在单链表中,NextElem的执行时间为O(1),而PriorElem的执行时间为O(n),为克服单链表这种单向性的缺点,可以利用双向链表。
在双向链表的节点中有两个指针域,其一指向直接后继,另一指向直接前驱。
二,基本操作
1,创建
typedef int datastyle;
typedef struct cyclelink_list{
datastyle data;
struct cyclelink_list*prior;
struct cyclelink_list*next;
}cyclenode,*cyclepoint;
//创建双向循环链表
cyclepoint create_list(void );
函数体:
cyclepoint create_list(void ){
cyclepoint H;
H= malloc(sizeof(cyclenode));
if(!H){
printf("malloc failed\n");
return NULL;
}
H->prior=H;
H->next=H;
return H;
}
2,头插数据
void insert_headlist(cyclepoint H,datastyle value){
cyclepoint p,t;
p= malloc(sizeof(cyclenode));
if(!p){
printf("malloc failed\n");
return;
}
//头插数据,让定位指针t指向H
p->data=value;
t=H;
p->next=t->next;
t->next->prior=p;
t->next=p;
p->prior=t;
}
3,尾差数据
void insert_rearlist(cyclepoint H,datastyle value){
cyclepoint p,t;
p= malloc(sizeof(cyclenode));
if(!p){
printf("malloc failed\n");
return;
}
//尾插数据,让定位指针指向头结点的前驱
t=H->prior;
p->data=value;
p->prior=t;
p->next=t->next;
t->next=p;
H->prior=p;
}
4,查找数据
cyclepoint locate_pos(cyclepoint H,int pos){
cyclepoint p;
int a=0;
p=H;
//判断pos是否合理
if(pos<=0){
printf("malloc failed\n");
return NULL;
}
while (p && a<pos){
p=p->next;
a++;
}
if(a==pos){
return p;
}
return NULL;
}
5,删除数据
datastyle pop_list(cyclepoint H,int pos){
cyclepoint p,r;
if(pos<=0){
printf("pos is invalid\n");
return -1;
}
//双向循环链表删除数据时,不用像单链表一样去寻找pos的前驱。他可以直接找pos所在的位置,再找前驱
else{
p= locate_pos(H,pos);
r=p;
p->prior->next=p->next;
p->next->prior=p->prior;
return r->data;
}
}
6,普通插入
void insert_list(cyclepoint H,datastyle value,int pos){
cyclepoint p,r;
p=locate_pos(H,pos);
r= malloc(sizeof(cyclenode));
if(!r){
printf("malloc failed\n");
return;
}
r->data=value;
r->next=p;
p->prior->next=r;
r->prior=p->prior;
p->prior=r;
}
7,销毁链表
void destroy_list(cyclepoint H){
cyclepoint p,r;
p=H;
while (p){
r=p;
p=p->next;
free(r);
r=NULL;
}
}
8,遍历
void show_list(cyclepoint H){
cyclepoint p;
p=H->next;
while (p!=H){
printf("%d\n",p->data);
p=p->next;
}
}
三、总结
当然,双向循环链表的操作还有很多,在这里我就不一一列举了。双向循环链表在插入和删除时要改的节点较多,建议先画图、想思路,再敲代码,这样会事半功倍的。
感谢观看!!!