95.【C语言】数据结构之双向链表的头插,头删,查找,中间插入,中间删除和销毁函数

news2024/11/13 14:24:56

目录

1.双向链表的头插

方法一

方法二

2.双向链表的头删

3.双向链表的销毁

4.双向链表的某个节点的数据查找

5.双向链表的中间插入

5.双向链表的中间删除

6.对比顺序表和链表


承接94.【C语言】数据结构之双向链表的初始化,尾插,打印和尾删文章

1.双向链表的头插

方法一

头插注意操作顺序:新节点与头节点的后一个节点建立联系,与头节点建立联系,反过来会丢失指针

void LTPushFront(LTNode* phead, LTDataType x)
{
	assert(phead);
	LTNode* newnode = BuyListNode(x);

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

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

方法二

当first保存了头节点的后一个节点的地址,可以反过来,即新节点与头节点建立联系,与头节点的后一个节点建立联系

void LTPushFront(LTNode* phead, LTDataType x)
{
	assert(phead);
	LTNode* newnode = BuyListNode(x);
    LTNode* first = phead->next;

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

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

2.双向链表的头删

void LTPopFront(LTNode* phead)
{
	assert(phead);
	assert(!LTEmpty(phead));
	LTNode* first = phead->next;
	LTNode* second = first->next;
	phead->next = second;
	second->prev = phead;
	free(first);
	first = NULL;
}

main.c的部分代码改为

void TestList()
{
	LTNode* plist = LTInit();
	LTPushBack(plist, 1);
	LTPushBack(plist, 2);
	LTPushBack(plist, 3);
	LTPushBack(plist, 4);
	LTPrint(plist);
	LTPopFront(plist);
	LTPrint(plist);
}

3.双向链表的销毁

void LTDestory(LTNode* phead)
{
	assert(phead);

	LTNode* cur = phead->next;
	while (cur != phead)
	{
		LTNode* next = cur->next;//保存cur1的下一个节点的地址
		free(cur);
		cur = next;
	}

	free(phead);
	phead = NULL;
}

注意:从phead的下一个节点开始逐步销毁每个节点,到cur值等于phead值时,停止循环

 备注:pos不置NULL也可以,形参的改变不影响实参(没有解引用操作) ,解决方法:在main.c中手动置NULL

4.双向链表的某个节点的数据查找

分为两种情况:找到和找不到

LTNode* LTFind(LTNode* phead, LTDataType x)
{
	assert(phead);

	LTNode* cur = phead->next;
	while (cur != phead)
	{
		if (cur->data == x)
		{
			return cur;//找到返回NULL
		}
		cur = cur->next;
	}
	return NULL;//找不到返回NULL
}

5.双向链表的中间插入

LTInsertBefore(LTNode* pos)表示在pos指向的节点之前(Before)插入(Insert)新节点

void LTInsertBefore(LTNode* pos,LTDataType x)
{
	assert(pos);
	LTNode* posprev = pos->prev;
	LTNode* newnode = BuyListNode(x);

	posprev->next = newnode;
	newnode->prev = posprev;

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

有了这个函数,而且有哨兵位的头节点,因此头插函数和尾插函数可以很容易改写

void LTPushFront(LTNode* phead, LTDataType x)
{
	assert(phead);
	LTInsertBefore(phead->next,x);
}

由于是循环链表,因此head的前一个节点为尾节点

void LTPushBack(LTNode* phead, LTDataType x)
{
	assert(phead);
	LTInsertBefore(phead,x);
}

中间插入函数应该和数据查找函数LTFind配合使用

main.c的部分代码改为

void TestList()
{
	LTNode* plist = LTInit();
	LTPushBack(plist, 1);
	LTPushBack(plist, 2);
	LTPushBack(plist, 3);
	LTPushBack(plist, 4);
	LTPrint(plist);
	LTNode* pfind = LTFind(plist, 3);
	LTInsertBefore(pfind, 5);
	LTPrint(plist);
}

5.双向链表的中间删除

void LTErase(LTNode* pos)
{
	assert(pos);
	LTNode* posprev = pos->prev;
	LTNode* posnext = pos->next;
 
	posprev->next = posnext;
	posnext->prev = posprev;

	free(pos);
	pos = NULL;
}

 备注:pos不置NULL也可以,形参的改变不影响实参(没有解引用操作) ,解决方法:在main.c中手动置NULL

中间删除函数应该和数据查找函数LTFind配合使用

main.c中部分代码改为

void TestList()
{
	LTNode* plist = LTInit();
	LTPushBack(plist, 1);
	LTPushBack(plist, 2);
	LTPushBack(plist, 3);
	LTPushBack(plist, 4);
	LTPrint(plist);
	LTNode* pfind=LTFind(plist, 3);
    if (pfind)
    {
	    LTErase(pfind);
        pfind==NULL;
    }
	LTPrint(plist);
}

注意要判断pfind是否为NULL!!

有了中间删除函数,头删和尾删函数可以变简洁

void LTPopFront(LTNode* phead)
{
	assert(phead);
	assert(!LTEmpty(phead));
	LTErase(phead->next);
}
void LTPopBack(LTNode* phead)
{
	assert(phead);
	assert(!LTEmpty(phead));
    LTErase(phead->prev);
}

6.对比顺序表和链表

不同点顺序表链表
存储空间上物理上一定连续逻辑上连续,但物理上不一定连续
随机访问支持O(1)不支持:O(N)
任意位置插入或者删除元素可能需要搬移元素,效率低O(N)只需修改指针指向
插入动态顺序表,空间不够时需要扩容没有容量的概念
应用场景元素高效存储+频繁访问任意位置插入和删除频繁
缓存命中率

缓存命中率是什么参见第96篇

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

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

相关文章

[极客大挑战 2019]PHP 1

[极客大挑战 2019]PHP 1 审题 猜测备份在www.zip中,输入下载文件。 知识点 反序列化 解题 查看代码 看到index.php中包含了class.php,直接看class.php中的代码 查看条件 当usernameadmin,password100时输出flag 构造反序列化 输入select中&#…

C++面试基础知识:排序算法 C++实现

上周实习面试,手撕代码快排没写出来,非常丢人,把面试官都给逗笑了。 基础不牢,地动山摇,基础的算法还是要牢记于心的。 插入排序 分为有序区和无序区,每次从无序区中选出一个,放到有序区域中。…

yarn报错`warning ..\..\package.json: No license field`:已解决

出现这个报错有两个原因 1、项目中没有配置许可证 在项目根目录package.json添加 {"name": "next-starter","version": "1.0.0",# 添加这一行"license": "MIT", }或者配置私有防止发布到外部仓库 {"priv…

批量缓存模版

批量缓存模版 缓存通常有两种使用方式,一种是Cache-Aside,一种是cache-through。也就是旁路缓存和缓存即数据源。 一般一种用于读,另一种用于读写。参考后台服务架构高性能设计之道。 最典型的Cache-Aside的样例: //读操作 da…

亚信安全并购亚信科技交易正式完成

亚信安全与亚信科技联合宣布,亚信安全正式完成对亚信科技的控股权收购,由此,规模近百亿的中国最大的软件企业之一诞生!双方将全面实现公司发展战略,以及优势能力与资源的深度融合,形成业界独有的“懂网、懂…

MybatisPlus入门(十)MybatisPlus-逻辑删除和多记录操作

一、Mybatis-Plus 多记录操作 按照主键删除多条记录 List<Long> ids Arrays.asList(new Long[]{2,3}) userDao.deleteBatchIds(ids); 示例代码如下: Testvoid testDelete(){//删除指定多条数据List<Long> list new ArrayList<>();list.add(14025513424818…

【css】overflow: hidden效果

1. 不添加overflow: hidden 1.1 效果 上面无圆角 1.2 代码 <template><view class"parent"><view class"child1">child1</view><view class"child2">child2</view></view></template><…

「QT」几何数据类 之 QPolygonF 浮点型多边形类

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「QT」QT5程序设计&#x1f4da;全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasolid…

架构篇(04理解架构的演进)

目录 学习前言 一、架构演进 1. 初始阶段的网站架构 2. 应用服务和数据服务分离 3. 使用缓存改善网站性能 4. 使用应用服务器集群改善网站的并发处理能力 5. 数据库读写分离 6. 使用反向代理和CDN加上网站相应 7. 使用分布式文件系统和分布式数据库系统 8. 使用NoSQL和…

OpenCV基础05_GUI和PyMsql

目录 一、PySimpleGUI 1、布局和窗口 2、文本框组件 3、视频处理 4、图片处理 二、pymsql 1、数据库操作 2、数据采集 3、人脸识别 一、PySimpleGUI PySimpleGUI 是一个用于简化 GUI 编程的 Python 包&#xff0c;它封装了多种底层 GUI 框架&#xff08;如 tkinter、…

ModuleNotFoundError: No module named ‘_ssl‘ centos7中的Python报错

报错 ModuleNotFoundError: No module named ‘_ssl’ 解决步骤&#xff1a; 1.下载openssl wget https://www.openssl.org/source/openssl-3.0.7.tar.gz tar -zxvf openssl-3.0.7.tar.gz cd openssl-3.0.72.编译安装 ./config --prefix/usr/local/openssl make make install3…

外呼系统只需这 3 种功能,电销效率快速提升

在当今竞争激烈的商业环境中&#xff0c;电销团队面临着诸多挑战。如何提高电销效率&#xff0c;成为了企业关注的焦点。今天&#xff0c;小编就给大家介绍&#xff0c;沃创云三种外呼系统功能&#xff0c;让你的电销效率快速提升。 一、智能拨号功能 传统的电销方式中&#x…

18. Mouse 鼠标、KeyBoard 键盘和 Action 消息事件处理

在本节的例子中&#xff0c;会自定义很多UI控件实现不同的事件响应&#xff0c;如下图所示&#xff1a; IOKit 事件框架 事件流程 OS X的事件依赖 IOKit 框架&#xff0c;事件发生后首先会传递到IOKit框架中处理&#xff0c;然后通知Window Server服务层处理&#xff0c;由…

C# 实现对指定句柄的窗口进行键盘输入的实现

在C#中实现对指定句柄的窗口进行键盘操作&#xff0c;可以通过多种方式来实现。以下是一篇详细的指南&#xff0c;介绍如何在C#中实现这一功能。 1. 使用Windows API函数 在C#中&#xff0c;我们可以通过P/Invoke调用Windows API来实现对指定窗口的键盘操作。以下是一些关键的…

Spring Plugin与策略模式:打造动态可扩展的应用

目录 一、策略模式 二、Spring Plugin 2.1 Spring Plugin 实现策略模式开发 2.2 策略模式优缺点 三、Spring Plugin 原理 一、策略模式 策略模式是一种设计模式&#xff0c;它允许程序在运行中动态的选择不同的行为方式进行动态执行。策略模式的核心思想是将行为封装在一个个…

Word大珩助手:超大数字怎么读?35位数字?69位数字?

俄罗斯日前对谷歌开出了20000000000000000000000000000000000&#xff08;35位数字&#xff09;美元的罚款 这一数字远超全球GDP总和&#xff0c;消息一出很快就登上热搜。 面对这样一个庞大的数字&#xff0c;人们不禁好奇&#xff0c;这样的数字该如何读出来&#xff1f; …

asp.net文件防盗链

URLRewriter实现 可以参考下面的文章 代码 .net framework 新建asp.net framework的web项目&#xff0c;新建AntiTheftChainHandler using System.Web;namespace AntiTheftChainStu01.Handler {public class AntiTheftChainHandler : IHttpHandler{public bool IsReusable…

【含开题报告+文档+PPT+源码】基于SSM的蛋糕店销售管理系统的设计与实现

开题报告 在现代社会&#xff0c;蛋糕作为一种受欢迎的甜点&#xff0c;广泛应用于各种庆祝活动和节日。传统的蛋糕预订方式往往需要用户亲自到店面进行预订&#xff0c;预订流程繁琐&#xff0c;时间和地点限制也给用户带来了不便。随着智能手机和移动互联网的普及&#xff0…

政治经济学笔记

【拯救者】政治经济学速成&#xff08;基础习题&#xff09; 研究生产关系必须联系生产力和上层建筑 1.生产力与生产关系 生产力代表生产的物质内容&#xff0c;生产关系是生产的社会形式。生产力决定生产关系&#xff0c;生产关系对生产力具有 反作用 *其中的”反作用”指的是…

005.精读《B-Tree vs LSM-Tree》

文章目录 1. 引言&#xff1a;2. 精读2.1 性能指标2.2 B-tree2.3 LSM-tree2.4 性能对比 3. 写在最后 1. 引言&#xff1a; 在本期的技术深度解析中&#xff0c;我们将聚焦于数据领域的两个重要成员——B-Tree和LSM-Tree。这两种数据结构在数据管理系统中最为普遍且广泛采用的数…