带头双向循环链表的增删改查

news2024/11/16 17:39:10

目录

  • 🤡前言
  • 😊带头双向循环链表
  • 👍链表实现
    • 😠插入-头插,尾插,随机插
    • ✅删除-头删,尾删,随机删
    • 😂链表搜索和链表修改
  • 💡总结


🤡前言

本篇博客主要是介绍带头双向循环链表的一些基本的增删改查的操作。

😊带头双向循环链表

在这里插入图片描述
如上图所示,我们所说的带头双向循环链表常指的是带有哨兵位头节点head,前一个结点的尾指针指向后一个节点,后一个节点的头指针指向前一个节点,并且最后一个节点的尾指针指向哨兵位节点,哨兵位节点的头指针指向最后一个节点,这就是双向带头循环链表。

👍链表实现

要实现带头双向循环链表,我们首先就需要创建出该相应的结构体。

typedef int LTDataType;
typedef struct ListNode
{
	LTDataType _data;
	struct ListNode* _next;
	struct ListNode* _prev;
}ListNode;

之后我们创建这个链表的哨兵位头节点并返回,我们用ListCreate()函数实现,如下代码。

	ListNode* ListCreate()
{
	ListNode* head = (ListNode*)malloc(sizeof(ListNode));
	head->_data = 0;
	head->_next = head;
	head->_prev = head;
	return head;
}

😠插入-头插,尾插,随机插

接下来就是对带头双向循环链表的插入,插入可以分为头插,尾插和随机插,我们用三个函数来实现。我们先进行头插ListPushFront(ListNode* pHead, LTDataType x);,如下代码。

ListNode* BuyNode(LTDataType x)
{
	ListNode* new = (ListNode*)malloc(sizeof(ListNode));
	new->_data = x;
	new->_next = NULL;
	new->_prev = NULL;
	return new;
}
void ListPushFront(ListNode* pHead, LTDataType x)
{
	assert(pHead);
	ListNode* p = BuyNode(x);
	p->_next = pHead->_next;
	pHead->_next->_prev = p;
	p->_prev = pHead;
	pHead->_next = p;
}

接下来我们进行尾插,尾插我们用函数ListPushBack(ListNode* pHead, LTDataType x);来实现,如下代码。

ListNode* BuyNode(LTDataType x)
{
	ListNode* new = (ListNode*)malloc(sizeof(ListNode));
	new->_data = x;
	new->_next = NULL;
	new->_prev = NULL;
	return new;
}
void ListPushBack(ListNode* pHead, LTDataType x)
{
	ListNode* p = BuyNode(x);
	ListNode* ret = pHead->_prev;
	p->_next = pHead;
	ret->_next = p;
	p->_prev = ret;
	pHead->_prev = p;
}

无论是头插还是尾插,只要我们找准哨兵位节点,谨慎使用好哨兵位节点的各个指针,就可以很简单的完成带头双向循环链表的头插和尾插。在完成头插和尾插后,最后我们还剩下一个随机插函数,随机插入我们用ListInsert(ListNode* pos, LTDataType x);函数完成,如下代码。

ListNode* BuyNode(LTDataType x)
{
	ListNode* new = (ListNode*)malloc(sizeof(ListNode));
	new->_data = x;
	new->_next = NULL;
	new->_prev = NULL;
	return new;
}
void ListInsert(ListNode* pos, LTDataType x)
{
	assert(pos);
	ListNode* p = BuyNode(x);
	p->_next = pos;
	p->_prev = pos->_prev;
	pos->_prev->_next = p;
	pos->_prev = p;
}

✅删除-头删,尾删,随机删

跟前面的插入一样,删除我们也有3种删除方式,分别是头删,尾删和随机删,接下来我们会一一将代码放出来。头删我们用函数ListPopFront(ListNode* pHead);来完成,代码如下。

void ListPopFront(ListNode* pHead)
{
	assert(pHead);
	ListNode* p = pHead->_next;
	p->_next->_prev = pHead;
	pHead->_next = p->_next;
	free(p);
}

尾删我们用函数ListPopBack(ListNode* pHead);来完成,代码如下。

void ListPopBack(ListNode* pHead)
{
	assert(pHead);
	ListNode* p = pHead->_prev;
	p->_prev->_next = pHead;
	pHead->_prev = p->_prev;
	free(p);
}

带头双向循环链表的头删和尾删都比较简单,关键点还是在于找准哨兵位头节点的头尾指针。接下来就是链表的随机删的实现,随机删除我们用函数ListErase(ListNode* pos);来完成,如下代码。

void ListErase(ListNode* pos)
{
	assert(pos);
	if (pos == pos->_next)
	{
		return;
	}
	pos->_prev->_next = pos->_next;
	pos->_next->_prev = pos->_prev;
	free(pos);
}

😂链表搜索和链表修改

在完成了链表的增加和删除后,剩下的就是链表的搜索和修改,链表的搜索我们用函数ListFind(ListNode* pHead, LTDataType x);来完成,如下代码。

ListNode* ListFind(ListNode* pHead, LTDataType x)
{
	assert(pHead);
	ListNode* p = pHead->_next;
	while (p != pHead)
	{
		if (p->_data == x)
		{
			return p;
		}
		p = p->_next;
	}
	return NULL;
}

链表的修改我们用函数ListModify(ListNode* pHead, LTDataType x)来完成,如下代码。

ListNode* ListFind(ListNode* pHead, LTDataType x)
{
	assert(pHead);
	ListNode* p = pHead->_next;
	while (p != pHead)
	{
		if (p->_data == x)
		{
			return p;
		}
		p = p->_next;
	}
	return NULL;
}
void ListModify(ListNode* pHead, LTDataType x)
{
	ListNode* p = ListFind(pHead, x);
	scanf("%d", &p->_data);
}

💡总结

到此为止,带头双向循环链表的增删改查就全完成了,带头双向循环链表是链表中使用起来最方便,功能最全的链表,因此我们合理的应用带头双向循环链表可以帮助我们事半功倍,解决不少问题。另外题外话,刚刚🐏康归来,好久都没写博客了,被这个疫情搞得一团糟,中招了是真难受啊,小伙伴们自己注意防护吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/130444.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt编写雷达模拟仿真工具(模拟点/歼击机/航母/发射导弹/爆炸效果/激光雷达等)

一、简单介绍 雷达模拟仿真工具,主要通过模拟点模拟相关物体,方位、航向角、距离、速度,并且显示相关详情信息可建立跟踪线建立与模拟点联系。可自定义更换模拟点背景达到更加逼真效果,如歼击机,航母发射导弹效果&…

单例模式,适配器模式,迭代器模式,工厂模式(C++实现)

设计模式就相当于编程中的“孙子兵法”,是经过很久的时间以及各路大神总结出来的多种实用,高效的业务设计中的套路; 单例模式 一个类只能创建一个对象的情况下的一种设计模式(eg:服务器只有一个),即单例模…

【论文阅读】《知识图谱研究综述》;Knowledge Graph:概念及主要应用,主要特征、构建的主要技术、未来研究方向。

目录 1. 文章来源2. 简介3. 什么是知识图谱4. Knowledge Graph 主要特征5. Knowledge Graph 构建的主要技术6. Knowledge Graph 未来研究方向1. 文章来源 该paper来自于知网,请尊重原创,这里仅作为学习笔记~ 2. 简介 知识图谱将知识库以一种图谱的形式展现出来,使知识具有…

opencv-python常用函数解析及参数介绍(一)——图像读取及其通道与灰度

opencv-python中一些常用函数解析及参数介绍前言1.读图片读彩图读灰度图2.显示图片显示彩图显示灰度图灰度图与彩图的区别从彩图中分离单通道通道合并3.保存图片4.灰图的通道分离5.读取视频前言 本文将简单介绍opencv-python中的图像以及视频的读取,并且介绍灰度图…

Hello 2023

年初到年尾,感觉刚写完《Hello 2022》,就要迎接2023了。今天是2022最后一天,本来是元旦假期的第一天,奈何要来公司加班,抽个时间来回顾下 2022 吧。 2022 年和2021 一样也是里程碑的一年,完成了两件大事&a…

使用CSS提高网站性能的30种方法

根据httparchive.org的页面重量报告,CSS在平均70个请求和2MB的网页上占7个HTTP请求和70Kb的代码。这并不是网站性能糟糕的最坏原因(我正看着你呢,JavaScript),但CSS面临着特定的挑战: CSS会阻止渲染&#x…

【C++进阶】多态

文章目录多态的概念多态的定义及实现抽象类多态的原理多继承和单继承关系中的虚表函数继承和多态常见的问题多态的概念 多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。 …

我的2022年,一位双非生的平淡一年

没有白走的路,每一步都算数🎈🎈🎈 前言 一谈到年终总结,其实还是很多的遗憾,我和大部分人一样,走过这一年的路途,发现自己除去每年头发越来越少,脸色日渐不佳。好像没有什…

Web 和移动应用程序测试之间的区别

智能手机改变了人类与技术互动的方式。无论是旅行、健身、生活方式、视频游戏,甚至是服务,都只需触手可及(字面意思就是如此)。我们只需要看看越来越多的智能手机或平板电脑用户与桌面用户就可以掌握这一现实。 根据一项调查,从 2021 年 4 月…

Dubbo(尚硅谷)学习笔记3

这是我们正常启动: 现在我们去把zookeeper注册中心关掉。 此时我们的注册中心是用不了的。 但是我们的数据还有,也就是我们的消费者还是能调用我们的提供者中的方法。 那么我们现在来试一下dubbo直连,也就是没有注册中心,我们也可…

VideoRender和ImageRender中的一些c++知识点

1.inline C中的inline用法_路痴的旅行的博客-CSDN博客 1 引入inline关键字的原因在c/c中,为了解决一些频繁调用的小函数大量消耗栈空间(栈内存)的问题,特别的引入了inline修饰符,表示为内联函数,栈空间就是…

深入理解计算机系统_静态链接和动态链接以及静态库和动态库

这篇文章记录静态链接和动态链接以及静态库和动态库的原理。 1 静态链接和动态链接 链接其实就是连接的意思,将所有相关的东西连接起来。 1.1 静态链接 什么是静态链接?编译时候的链接就是静态链接,所以ld/collect2链接程序,也…

公司让我一个人干数据中台,是不是可以准备找下家了

大数据群里,有个哥们问了下面这样一个问题,让刚刚阳康返工的群友们笑的心跳加速,直接炸锅。 开工有惊喜 一个人搞一个数据中台!这是啥神仙领导做出来的决策?是发烧的时候拍脑袋定的吗?热心的群友也都给出了…

vector类的使用

目录 ​一、vector类的组织形式 二、vector类的成员函数 1.默认成员函数 (1)构造函数、拷贝构造函数 (2)析构函数和赋值运算符重载 2.容量操作 3.迭代器(iterator) 4.元素访问 5.修改操作 一、vec…

web3调研:Dusk Network调研

在此声明,仅做分享,绝不存在倡导炒币行为 原文链接:Dusk 调研报告 web3产品调研系列 1、web3调研:Iron fish调研 2、web3调研:Dusk Network调研 目录web3产品调研系列一、背景概述二、项目介绍2.1 创始团队2.2 项目融…

【数据结构】三万字图文讲解带你手撕八大排序(附源码)

👑作者主页:进击的安度因 🏠学习社区:进击的安度因(个人社区) 📖专栏链接:数据结构 文章目录一、前言二、排序的概念和运用三、八大排序讲解及实现1、直接插入排序1.1 排序思路1.2 代…

Java重点源码回顾——ConcurrentHashMap1.7

1. 概述 HashMap在我们的日常生活中使用很多,但是它不是线程安全的。我们可以使用HashTable来代替,主要实现方式是在方法中加入synchronized,所以效率也比较低。因此,对于键值对,我们可以尝试使用ConcurrentHashMap来…

《Java 后端面试经》微服务篇

《Java 后端面试经》专栏文章索引: 《Java 后端面试经》Java 基础篇 《Java 后端面试经》Java EE 篇 《Java 后端面试经》数据库篇 《Java 后端面试经》多线程与并发编程篇 《Java 后端面试经》JVM 篇 《Java 后端面试经》操作系统篇 《Java 后端面试经》Linux 篇 《…

关于Linux 网络抓包的一些笔记整理

写在前面 遇到一个 ping 单通 的情况,需要抓包分析下,所以整理这部分笔记博文内容涉及: HTTP/TCP 抓包分析 DemoICMP 抓包分析 DemoNginx 抓包分析用户名密码 Demo 理解不足小伙伴帮忙指正 这世界的存在完全只是就它对一个其他事物的&#xf…

【自学Java】Java选择结构if

Java选择结构if Java语言if条件判断 在 Java 中,关键字 if 是用于测试某个条件(布尔型或逻辑型)的语句是否满足一定的条件,如果满足特定的条件,则会执行 if 后面的大括号 {} 括起来的代码块,如果没有代码…