双向链表

本文详细介绍了双向链表的概念,包括其基本定义和结构,重点讲解了如何进行插入和删除操作,通过实例演示了在特定场景下如何实现这些操作。

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

双向链表定义如下:

typedef struct list
{
	struct list *fwd;
	struct list *bwd;
	int data;
} list;

根节点root不带数据,root->fwd指向首节点,root->bwd指向尾节点,链表为空时,两者均为NULL。

普通节点中,fwd指向正向的后一个,bwd指向反向的前一个。

首节点的bwd为NULL,尾节点的fwd为NULL。

下面的例子中,数据不重复,升序排列。

插入:

插入在pCur和pNext之间,一般操作为:

1. pCur->fwd指向pNode

2. pNode->fwd指向pNext

3. pNext->bwd指向pNode

4. pNode->bwd指向pCur

1和2是通用操作,3和4需要根据首尾节点分别处理。

插入在尾节点之后,则步骤3不需要,但要更新root->bwd,使其指向新的尾节点pNode。

插入在首节点之前,则步骤4不需要,但要更新root->fwd,使其指向新的首节点pNode(由步骤1统一完成)。还要将新的首节点pNode->fwd置为NULL。

int insert_list(list *root, int data)
{
	list *pCur, *pNext, *pNode;

	for (pCur = root; (pNext = pCur->fwd) != NULL; pCur = pNext)
	{
		if (pNext->data > data)
		{
			break;
		}
	}

	pNode = malloc(sizeof(list));
	if (NULL == pNode)
	{
		return -1;
	}
	pNode->data = data;
	pNode->fwd = pNext;
	pCur->fwd = pNode;

	if (pCur != root)
	{
		pNode->bwd = pCur;
	}
	else
	{
		pNode->bwd = NULL;
	}

	if (pNext != NULL)
	{
		pNext->bwd = pNode;
	}
	else
	{
		root->bwd = pNode;
	}

	return 0;
}

删除:

删除pNext(若存在),一般操作为:

1. pCur->fwd指向pNext->fwd

2. pNext->fwd->bwd指向pNext->bwd(注意不能用pCur替换)

若是删除尾节点,则步骤2不需要,但要更新root->bwd,使其指向新的尾节点pNext->bwd。

int remove_list(list *root, int data)
{
	list *pCur, *pNext;

	for (pCur = root; (pNext = pCur->fwd) != NULL; pCur = pNext)
	{
		if (pNext->data == data)
		{
			break;
		}	
	}

	if (pNext)
	{
		pCur->fwd = pNext->fwd;

		if (pNext->fwd != NULL)
		{
			pNext->fwd->bwd = pNext->bwd; // not pCur
  		}
		else
		{
			root->bwd = pNext->bwd;
		}

		free(pNext);
	}

	return 0;
}

用法:

	list list;

	list.fwd = NULL;
	list.bwd = NULL;
	list.data = -1;
	...
	insert_list(&list, n);
	...
	remove_list(&list, n);



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值