单链表有一个缺点,当访问任何结点,都必须知道头指针,不能逆着进行。而双向链表则是添加了一个指针域,通过两个指针,分别指向结点的前一个结点和后一个结点,这样就弥补了单向链表的不足,就可以通过双链表的任何结点访问到它的前一个结点和后一个结点。
双向链表中的两个指针域,一个存储前驱节点的地址,一个存储后继结点的地址。
接下来展示代码及注释:
#include<stdio.h>
#include<stdlib.h>
struct node{
int data;
struct node* prior;
struct node* next;
};
//尾插法创建双循环链表-----------------------------------------------------------------
struct node* creatbyrear()
{
struct node* head=(struct node*)malloc(sizeof(struct node));//创建头结点,也是返回值
head->next = head->prior =head; //初始化为空链表
struct node* newnode; //定义新结点
struct node* tail=head; //一直指向尾结点的指针
printf("请输入数字(输入 -1 代表结束):");
while (1)
{
newnode=(struct node*)malloc(sizeof(struct node));
scanf("%d",&newnode->data );
if (-1==newnode->data)
break;
else
{
head->prior =newnode;//头结点与在尾部的结点连接
newnode->next =head; //头结点与在尾部的结点连接
newnode->prior=tail; //新结点与前面的结点连接
tail->next =newnode; //新结点与前面的结点连接
tail=newnode ;
}
}
return head;
}
//头插法创建双循环链表-------------------------------------------------------------------
struct node* creatbyhead()
{
struct node* head=(struct node*)malloc(sizeof(struct node));//创建头结点,也是返回值
head->next = head->prior =head; //初始化为空链表
struct node* newnode; //定义新结点
printf("请输入数字(输入 -1 代表结束):");
while (1)
{
newnode=(struct node*)malloc(sizeof(struct node));
scanf("%d",&newnode->data );
if (-1==newnode->data)
break;
else
{
newnode->prior =head;
newnode->next =head->next ;
head->next->prior =newnode;
head->next =newnode; //这一步最后再写,前面三步是将新结点与head后面的所有结点连接起来
}
}
return head;
}
//删除结点----------------------------------------------------------------------------
void Delete(struct node* head,int i)
{
struct node* p=head->next ;
int j;
for (j=0;j<i-1 && p;++j)
{
p=p->next ; //p指向第i个结点
}
if (p!=head)
{
p->prior ->next=p->next ;
p->next ->prior=p->prior;
free(p); //上面提到的删除就是这里的free函数释放内存空间
}
}
//打印链表--------------------------------------------------------------------------
void output(struct node* head)
{
struct node* move=head->next ;
while (move!=head) //当move移动到头结点时链表为空,就可以结束了
{
printf("%d\t",move->data );
move=move->next ;
}
printf("\n");
}
//主函数------------------------------------------------------------------------------
int main()
{
struct node* h1;
struct node* h2;
h1=creatbyrear();
output(h1);
h2=creatbyhead();
output(h2);
Delete(h1,2);
printf("删除后的结果:");
output(h1);
return 0;
}