带头双向循环链表

文章目录

概述

带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了,后面我们代码实现了就知道了。

双向循环链表含有一个头节点(哨兵位),含有两个指针域,next,prev,分别指向节点的后继和前驱。需要注意的是,头节点的prev指向尾节点,尾节点的next指向头节点

看着复杂,实际操作起来很简单。

初始化

和单链表初始化差不多,无非就是多了一个prev指针

c 复制代码
LTNode* CreateLTNode(LTDataType x)
{
	LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}

	newnode->val = x;
	newnode->next = NULL;
	newnode->prev = NULL;

	return newnode;
}

LTNode* LTInit()
{
	LTNode* phead = CreateLTNode(-1);
	phead->next = phead;
	phead->prev = phead;

	return phead;
}

销毁

遍历链表,并定义一个next 来保存 cur 的下一个节点,在链表都free 完后,再销毁头节点;

注意:应该是从头节点的 next 开始遍历。

c 复制代码
void ListNodedestroy(LNode* phead)
{
	assert(phead);
 
	LNode* cur = phead->next;
	while (cur != phead)
	{
		LNode* next = cur->next;
		free(cur);
		cur = next;
	}
 
	free(phead);
	phead = NULL;
}

插入

找到 pos 的前驱 prev ;

将前驱,pos,新节点链接起来。

c 复制代码
void LTInsert(LTNode* pos, LTDataType x)
{
	assert(pos);

	LTNode* posPrev = pos->prev;
	LTNode* newnode = CreateLTNode(x);

	// posprev newnode pos
	posPrev->next = newnode;
	newnode->prev = posPrev;
	newnode->next = pos;
	pos->prev = newnode;
}

删除

找到 pos 的前驱和后继;

链接其前驱,后继;

删除pos。

c 复制代码
void LTErase(LTNode* pos)
{
	assert(pos);

	LTNode* posNext = pos->next;
	LTNode* posPrev = pos->prev;

	posPrev->next = posNext;
	posNext->prev = posPrev;
	free(pos);
	//pos = NULL;
}

遍历打印

c 复制代码
void LTPrint(LTNode* phead)
{
	assert(phead);
	printf("哨兵位<=>");

	LTNode* cur = phead->next;
	while (cur != phead)
	{
		printf("%d<=>", cur->val);
		cur = cur->next;
	}
	printf("\n");
}
相关推荐
Anastasiozzzz18 小时前
深入研究Redis的ZSet底层数据结构:从 Ziplist 的级联更新到 Listpack 的完美救场
数据结构·数据库·redis
Eward-an18 小时前
LeetCode 1980 题通关指南|3种解法拆解“找唯一未出现二进制串”问题,附Python最优解实现
python·算法·leetcode
程序员酥皮蛋18 小时前
hot 100 第四十题 40.二叉树的层序遍历
数据结构·算法·leetcode
※DX3906※19 小时前
Java排序算法--全面详解面试中涉及的排序
java·开发语言·数据结构·面试·排序算法
木斯佳19 小时前
HarmonyOS 6实战:从爆款vlog探究鸿蒙智能体提取关键帧算法
算法·华为·harmonyos
Mr.朱鹏20 小时前
JVM-GC垃圾回收案例
java·jvm·spring boot·算法·spring·spring cloud·java-ee
WJSKad123520 小时前
【DepthPro】实战教程:单目深度估计算法详解与应用
算法
wzqllwy20 小时前
8 大经典排序算法(Java 实现):原理 + Demo + 核心分析
java·算法·排序算法
We་ct20 小时前
LeetCode 77. 组合:DFS回溯+剪枝,高效求解组合问题
开发语言·前端·算法·leetcode·typescript·深度优先·剪枝
重生之我是Java开发战士20 小时前
【递归、搜索与回溯】二叉树中的深度优先搜索:布尔二叉树,求根节点到叶节点数字之和,二叉树剪枝,验证二叉搜索树,第K小的元素,二叉树的所有路径
算法·深度优先·剪枝