首先讲循环链表,简单来说就是让链表首尾相连,形成一个环,因为一般的链表都是单向的,任意给出的一个节点是不能访问前面的链节,这就导致了单向链表的局限性,循环链表从一定程度上来说就解决了这一问题,通过表头指针的移动,因为环的特性,可以访问完整个链表;
但是我们不禁会想,如果只是为了访问已知链节的前一个节点,通过循环虽然达到了访问的目的,但是走遍整个链表岂不是太花费时间了么,就好比北京——天津——上海——北京的路线,从天津出发前往北京,需要先跑去中国南边的上海,岂不是自己找罪受,所以,这里引入了双向链表。
双向链表和单向链表的建立方法是类似的,只是加入了一个*front指针记录前一个链节的地址,这和*next指针的作用恰恰相反,同样,next实现的是链表的单向,反之,front实现的就是链表的逆向,通过指针的滑动访问链表这个道理是通用的
//双向链表的建立与数据读取
#include <stdio.h>#include <stdlib.h>
struct node
{
int data;
struct node *next;
struct node *front;
};
int main()
{
struct node *p1,*p2,*q1,*head;
int i,num;
p1=p2=q1=head=(struct node *)malloc(sizeof(struct node));
head->next=p1;
while(scanf("%d",&num)&&num!=-1)//这里的输入要在20个数以内,方便下方循环链表的实现
{
p1=(struct node *)malloc(sizeof(struct node));
p1->data=num;
p2->next=p1;
p1->front=p2; //除了这条语句,其他语句与单向尾插法链表的相同
p2=p1;
}
p1->next=head;//将链尾与链头连接起来,形成循环
p2=head->next;
printf("链表的正向输出:");
while(p2!=head)
{
printf("%d ",p2->data);
p2=p2->next;
}
printf("\n");
printf("链表的逆向输出");
while(p1!=head)
{
printf("%d ",p1->data);
p1=p1->front;
}
printf("\n");
printf("链表的循环输出:");
p2=head->next;
for(i=0;i<20;i++)
{
if(p2==head)
p2=p2->next;
else
{
printf("%d ",p2->data);
p2=p2->next;
}
}
printf("\n");
free(p2);
return 0;
}