【数据结构】‘双向链表’冲冲冲

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤

📃个人主页 :阿然成长日记 👈点击可跳转

📆 个人专栏: 🔹数据结构与算法🔹C语言进阶

🚩 不能则学,不知则问,耻于问人,决无长进

🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍

文章目录

构建节点

c 复制代码
//构建节点
LTNode* BuyLTNode(LTDataType x)
{
	LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));
	if (newnode == NULL)
	{
		perror("newnode fail");
		exit(-1);
	}
	newnode->data = x;
	return newnode;
}

初始化

我们的节点是双向循环链表

c 复制代码
//初始化
LTNode* LTInit()
{
	LTNode* phead = BuyLTNode(-1);
	phead->next = phead;
	phead->prev = phead;
	return phead;
}

打印

c 复制代码
//打印
void print(LTNode* phead)
{
	assert(phead);
	printf("phead<=>");
	LTNode* cur = phead->next;
	while (cur != phead)
	{
		printf("%d<=>", cur->data);
		cur = cur->next;
	}
	printf("\n");
}

尾插

思路:

代码:

c 复制代码
void LTPushBack(LTNode* phead, LTDataType x)
{
	assert(phead);
	LTNode* tail = phead->prev;
	LTNode* newnode = BuyLTNode(x);
	newnode->prev = tail;
	tail->next = newnode;

	newnode->next = phead;
	phead->prev = newnode;
}

尾删

思路:

代码:

c 复制代码
//尾删
void LTPopBack(LTNode* phead)
{
	assert(phead);
	assert(phead->prev!=phead);
	LTNode* cur = phead->prev->prev;
	free(cur->next);
	cur->next = phead;
	phead->prev = cur;
}

运行结果:

头插

思路:

代码;

c 复制代码
//头插
void LTPushFront(LTNode* phead, LTDataType x)
{
	assert(phead);
	LTNode* newnode = BuyLTNode(x);
	//先改newnode节点后
	newnode->next = phead->next;
	phead->next->prev = newnode;
	//在改前
	newnode->prev = phead;
	phead->next = newnode;

}

运行结果:

头删

思路:

代码:

c 复制代码
//头删
void LTPopFront(LTNode* phead)
{
	assert(phead);
	assert(phead->next != phead);
	LTNode* cur = phead->next->next;
	free(phead->next);
	//链接顺序不能变
	phead->next = cur;
	phead = cur->prev;
}

运行结果:

计算链表长度

//如果让哨兵节点的内容是链表长度 ,那么,data的数据类型必须是int型。

c 复制代码
//链表长度
//如果让哨兵节点的内容是链表长度 ,那么,data的数据类型必须是int型。
int LTSize(LTNode* phead)
{
	int size = 0;
	LTNode* cur = phead->next;
	while (cur != phead)
	{
		size++;
		cur = cur->next;
	}
	return size;
}

查找

pos位置插入(一般都是pos之前)

思路:

代码:

c 复制代码
//pos位置插入(一般都是pos之前)
void LTInsert(LTNode* pos, LTDataType x)
{
	assert(pos);
	LTNode* newnode = BuyLTNode(x);
	LTNode* cur = pos->prev;
	//先链接newnode后
	newnode->next = pos;
	pos->prev = newnode;
	//再链接newnode前
	cur->next = newnode;
	newnode->prev = cur;
}

删除pos位置

思路:代码:

c 复制代码
//删除pos位置
void LTErase(LTNode* pos)
{
	assert(pos);
	LTNode* posprev = pos->prev;
	LTNode* posnext = pos->next;

	free(pos);
	//链接顺序不能变
	posprev->next = posnext;
	posnext->prev = posprev;
}

删除时的注意点

链接顺序不能变的原因: 如果先posnext->prev = posprev;

(此时posnext->prev仍然指向原来pos节点地址,
因为我们free的是pos节点内容,他的地址仍在,
不会改变其他节点的指向。 )
那么等于posprev又重新指向了pos地址,
所以在打印时,会出现一串地址

相关推荐
不正经学生2 小时前
C语言预处理详解:编译器真正动手之前的那些事
c语言·开发语言·算法·面试·bug
毕竟是shy哥5 小时前
计算YOLO数据集中每个类的目标数
算法·yolo·机器学习
M78佐菲5 小时前
Linux学习笔记:TCP协议
linux·笔记·学习·tcp/ip·算法
晊晌_h6 小时前
嵌入式从0到精通——数据结构总结[特殊字符]
数据结构·算法·排序算法
我找到地球的支点啦7 小时前
Matlab系列(009) 一CRC循环冗余校验详解
开发语言·数据结构·算法·matlab·信息与通信
罗西的思考7 小时前
【OpenClaw具身硬件】ZeroClaw 源码阅读笔记(3)--- RAG
人工智能·算法·机器学习
浪里镖客8 小时前
位姿转换矩阵写法-个人习惯(计算机理解其实是相反的)
线性代数·算法·矩阵
小白羊丨11 小时前
如何诊断 Prompt 模板导致的效果下降?
人工智能·算法·prompt
OPEN-F12 小时前
C++11/14新特性精讲:移动语义与智能指针实战
开发语言·c++·算法
lisin-lee-cooper12 小时前
【leetcode658】有序数组找出k个最接近x的数
java·数据结构·算法