双向循环链表
众所周知,单向链表想要查找当前节点的上一个数据,必须得重新把链表遍历一遍,十分浪费资源;(这也是链表不如数组高效的一个方面,数组只需要知道下标即可一步到位)
而如果可以创建一种双向的链表,这种浪费就可以得到一定程度的缓解,且对于链表的操作灵活性也会提升。
在p节点前插入r的顺序(节点的个数是从1开始数的,不是0!!!所以是插入第n号节点后面,而p是n+1号节点):
r->next=p;
r->prior=p->prior;
p->prior->next=r;
p->prior=r;
不要搞错顺序!
话不多说,上代码!
#include <stdio.h>
#include <stdlib.h>
//双向循环链表
int nodeNumber=0;
typedef struct node
{
int data;
struct node *prior;//前指
struct node *next;//后指
}sqlist,*linklist;
linklist CreateList()
{
linklist head;
linklist s,r;
head=NULL;
r=head;
int n;
printf("是否开始创建双向循环链表?yes1/no0\n");
scanf("%d",&n);
if(n!=1)
return head;
while(1)
{
if(n==1)
{
s=(linklist)malloc(sizeof(sqlist));
s->data=nodeNumber;
nodeNumber++;
if(head==NULL)
head=s;
else
{
r->next=s;//正向
s->prior=r;//反向
}
r=s;
}
else
{
//形成闭环
r->next=head;
head->prior=r;
break;
}
printf("是否创建新节点?yes1/no0\n");
scanf("%d",&n);
}
return head;
}
void InsertNode(linklist head)
{
printf("插入节点\n");
printf("请问要插入第几号节点后?\n");
int n,i;
scanf("%d",&n);
if(n>nodeNumber||n<1)
{
printf("输入错误!\n");
return;
}
linklist p=head;
for(i=0;i<n;i++)
{
p=p->next;
}
linklist r;
r=(linklist)malloc(sizeof(sqlist));
r->data=666;
//四步插入
r->next=p;
r->prior=p->prior;
p->prior->next=r;
p->prior=r;
nodeNumber++;
}
linklist DeleteNode(linklist head)
{
printf("删除节点\n");
printf("请问要删除第几号节点?\n");
int n,i;
scanf("%d",&n);
if(n>nodeNumber||n<1)
{
printf("输入错误!\n");
return head;
}
linklist p=head;
for(i=0;i<n-1;i++)
{
p=p->next;
}
p->next->prior=p->prior;
p->prior->next=p->next;
if(n==1)
head=p->next;
free(p);
nodeNumber--;
return head;
}
void DisplayList(linklist head)
{
printf("展示全表\n");
int i;
linklist p=head;
if(nodeNumber==0)
{
printf("链表为空!\n");
return;
}
printf("正向展示:\n");
for(i=0;i<nodeNumber;i++)
{
printf("%d--",p->data);
p=p->next;// 注意这里打印和移动的顺序
}
printf("\n");
printf("反向展示:\n");
for(i=0;i<nodeNumber;i++)
{
p=p->prior;//反向先把p移到head前一位
printf("%d--",p->data);
}
printf("\n");
}
int main()
{
linklist p;
printf("双向循环链表简易创建、插入、删除、展示\n\n");
p=CreateList();
DisplayList(p);
InsertNode(p);
DisplayList(p);
p=DeleteNode(p);
DisplayList(p);
getchar();//吃回车
getchar();//防闪退
return 0;
}