双向循环链表的创建和删除

        单链表有一个缺点,当访问任何结点,都必须知道头指针,不能逆着进行。而双向链表则是添加了一个指针域,通过两个指针,分别指向结点的前一个结点和后一个结点,这样就弥补了单向链表的不足,就可以通过双链表的任何结点访问到它的前一个结点和后一个结点。

        双向链表中的两个指针域,一个存储前驱节点的地址,一个存储后继结点的地址。

        接下来展示代码及注释:

#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;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不怕娜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值