线性表4:双向循环链表

本文详细介绍了双向循环链表的基本概念、特点及其实现方法,包括链表的创建、节点的插入与删除等核心操作,并提供了完整的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一次介绍了单向循环链表,这一次介绍双向循环链表。

链表的特点

顾名思义,双向循环链表的结点中有两个指针域,一个指向直接后继,一个指向直接前驱。

链表的描述

描述: 数据域+两个指针域

typedef int datatype;

typedef struct node {
	datatype data;
	struct node * prior;
	struct node * next;
}dlinklist, *dlinklist_t;

基本操作

创建空链表

用malloc动态申请空间

dlinklist_t createDLinkList()
{
	//1.申请空间
	dlinklist_t H = (dlinklist_t)malloc(sizeof(dlinklist));
	if(NULL == H)
	{
		printf("malloc head node fail\n");
		return NULL;
	}

	//2.赋值:数据无效,两个指针都指向自己
	H->data = -1;
	H->prior = H;
	H->next = H;

	return H;
}

第一种插入方式:头插

头插,新结点永远插入第一项(头结点不是第一项,头结点后面才是第一项)
头插
代码的书写顺序可以有很多种,只要逻辑通顺即可。

int headInsert(dlinklist_t H, datatype x)
{
	//1.封装结点
	dlinklist_t pnew = (dlinklist_t)malloc(sizeof(dlinklist));
	if(NULL == pnew)
	{
		printf("malloc new node fail\n");
		return -1;
	}

	pnew->data = x;

	//2.接入头结点后面
	pnew->prior = H;
	pnew->next = H->next;
	H->next->prior = pnew;
	H->next = pnew;

	return 0;
}

输出链表

void showDLinkList(dlinklist_t H)
{
	dclinkPtr p = H->next;

	while(p != H)
	{
		printf("%d ", p->data);
		p = p->next;
	}
	printf("\n");
}

单链表中,取第i个元素必须从头结点出发寻找。
按位置查找,查找第pos项元素,返回其地址

dlinklist_t searchPos(dlinklist_t H, int pos)
{
	int count = -1;
	dlinklist_t p = H;

	if(pos < 0)
	{
		printf("位置不合法:pos < 0\n");
		return NULL;
	}

	while(count < pos)
	{
		p = p->next;
		count++;

		if(p == H)
		{
			printf("位置不合法:pos > 表长\n");
			return NULL;
		}
	}

	return p;
}

第二种插入方式:任意位置插入新结点

要利用上面的查找函数searchPos()
在这里插入图片描述

int insertDLinkList(dlinklist_t H, int pos, datatype x)
{
	dlinklist_t pnew = NULL;//新增结点
	dlinklist_t p = searchPos(H, pos);//找位置
	if(NULL == p)	//位置合法不?
		return -1;

	//2.封装新结点
	pnew = (dlinklist_t)malloc(sizeof(dlinklist));
	if(NULL == pnew)
	{
		printf("malloc newnode fail\n");
		return -1;
	}

	pnew->data = x;

	//3.插入新增结点
	pnew->prior = p->prior;
	pnew->next = p;
	p->prior->next = pnew;
	p->prior = pnew;

	return 0;
}

删除结点
在这里插入图片描述

int deleteDLinkList(dlinklist_t H, int pos, datatype *x)
{
	//1.找位置
	dlinklist_t p = searchPos(H, pos);
	if(NULL == p)
		return -1;

	//2.删除
	p->prior->next = p->next;
	p->next->prior = p->prior;

	//3.释放该结点空间
	*x = p->data;
	free(p);
	p = NULL;

	return 0;
}

测试

dlinklist_t H = createDLinkList();
	if(NULL == H)
	{
		printf("createDLinkList fail\n");
		return -1;
	}

	headInsert(H, 4);
	headInsert(H, 3);
	headInsert(H, 2);
	headInsert(H, 1);
	showDLinkList(H);
	
	int pos = 2;
	dlinklist_t p = searchPos(H, pos);
	printf("下标%d = %d\n", pos, p->data);

	insertDLinkList(H, 2, 666);
	insertDLinkList(H, 2, 777);
	insertDLinkList(H, 2, 888);
	printf("insert: ");
	showDLinkList(H);

	datatype x;
	deleteDLinkList(H, 2, &x);
	deleteDLinkList(H, 2, &x);
	deleteDLinkList(H, 2, &x);
	printf("delete: ");
	showDLinkList(H);
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值