双向循环链表
单链表只能向一个方向进行,也就是说元素可以直接找到后继,但不能直接找到前驱。 双向链表可以允许一个元素直接找到其后继,也可以直接找到其前驱
区别就在于:单链表中只存储了下一个元素的地址,双向链表在此基础之上增加了上一个元素的地址。
#include<stdio.h>
#include<stdlib.h>
typedef int ElemType;
typedef struct Node{
ElemType data;
struct Node *prior; //前驱的指针域
struct Node *next; //后继的指针域
}Node,DoubleCirLinkList; //双向循环链表
Node *R;
void init(DoubleCirLinkList *L){
L->data=0;
L->next=L;
L->prior=L;
for(int i=1;i<=10;i++){
Node *n=malloc(sizeof(Node));
n->data=i;
n->next=R->next;
R->next=n;
R=n;
L->prior=R;
L->data++;
}
}
void show(DoubleCirLinkList *L){
Node *p=L;
printf("[");
while(1){
p=p->next;
if(p=R){
printf("%d]\n",p->data);
break;
}else{
print("%d,",p->data);
}
}
}
void insert(DoubleCirLinkList *L,int position,ElemType e){
if(position<1||position>L->data+1){
printf(">>>插入位置不合法!\n");
return;
}
Node *p=L;
// 没数据插第一个 有数据最后一个
if(position==1&&L->data==0){
Node *n=malloc(sizeof(Node));
n->data=e;
n->next=R->next;
R->next=n;
R=n;
L->prior=R;
L->data++;
}else{
Node *p=L;
for(int i=1;i<position;i++){
p=p->next;
}
Node *n=malloc(sizeof(Node));
n->data=e;
p->next->prior=n;
n->next=p->next;
p->next=n;
n->data++;
}
for(int i-1;i<position;i++){
p=p->next;
}
}
void delete(DoubleCirLinkList *L,int position,ElemType *e){
if(L->data==0){
printf("空表!\n");
return;
}
if(position<1||position>L->data){
printf(">>>删除位置不合法!\n");
}
if(position==1&&L->data==1){ // 只有一个·元素
}else if(position==L->data&&L->data>1){
Node *n=L->next;
*e=n->data;
free(n);
L->data--;
L->next=L;
L->prior=L;
R=L; // 重置R指针
}else if(position==L->data&&L->data>1){ // 删尾
Node *n=R;
R->prior->next=R->next;
R->next->prior=R->prior;
R=R->prior;
*e=n->data;
free(n);
L->data--;
}else{
Node *p=L;
for(int i=1;i<position;i++){
p=p->next;
}
Node *n=p->next;
n->next->prior=p;
p->next=n->next;
L->data--;
*e=n->data;
free(n);
}
}
void main(){
DoubleCirLinkList L;
int choice;
ElemType e;
printf("------------双向循环链表---------\n");
printf("1.初始化\n");
printf("2.插入\n");
printf("3.删除\n");
printf("4.打印\n");
printf("0.退出\n");
while(1){
printf(">>>请选择:");
scanf("%d",&choice);
switch(choice){
case 1:
init(&L);
break;
case 2:
printf(">>>请输入插入的位置:");
scanf("%d",&position);
printf(">>>请输入插入的元素:");
scanf("%d",e);
insert(&L,position);
break;
case 3:
printf(">>>请输入删除的位置:");
scanf("%d",&position);
delete(&L,position,&e);
printf(">>>删除元素%d\n",e);
break;
case 4:
show(&L);
break;
case 0:
return;
}
}
}