带头双向循环链表的实现

前言

之前讲过单链表的实现,在实现的过程中,我们会发现每次删除或者在前面插入节点的时候,都要提前保存上一个节点的地址。这样做十分麻烦,所以就有了单链表的升级,双链表。今天就来实现一个带头双向循环的双链表。

带头: 指有一个哨兵位的头节点,头节点不拿来存放有效值
双向: 代表是个双向链表,一个指针存放前一个节点地址,一个地址存放后一个节点地址。
循环: 最后一个节点的下一个节点是头节点。
在这里插入图片描述

节点声明

刚刚提到过,双向链表是有2个指针的,一个指针指向前一个节点,一个指针指向后一个节点,还有一个来存放数据。

//存放的类型
typedef int ListValType;

//节点结构体声明
typedef struct ListNode
{
   
	ListValType val;
	struct ListNode* prve;
	struct ListNode* next;
}LSNode;

链表的初始化

因为我们是带哨兵头的链表,所以链表需要初始化。
初始化我们只需要开辟一个头节点,但这个节点我们不存放有效值。
而因为是循环链表,所以最后一个节点要指向第一个节点,只有一个节点时,自己指向自己。
在这里插入图片描述
初始化代码

//链表初始化
LSNode* ListInto()
{
   
	//创建一个节点
	LSNode* newNode = (LSNode*)malloc(sizeof(LSNode));
	//指向自己
	newNode->next = newNode;
	newNode->prve = newNode;
	
	return newNode;
}

在这里插入图片描述
调试后发现它的next和prve指针都指向自己,说明初始化完成了。

尾插

那么我们就可以写个尾部插入来玩玩,我们都知道头节点的前一个地址是指向最后一个地址的。所以就可以直接找到尾节点进行插入。
在这里插入图片描述


//创建节点
LSNode* CreateListNode(ListValType x)
{
   
	LSNode* newNode = (LSNode*)malloc(sizeof(LSNode));
	if (newNode == NULL)
	{
   
		//空间开辟失败,不玩了
		exit(-1);
	}
	newNode->val = x;
	return newNode;
}

//尾插
void ListPushBack(LSNode* phead, ListValType x)
{
   
	//断言
  • 34
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 37
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 37
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值