网站集约化建设 技术/廊坊seo优化
前言
hello,大家好呀,我是Humble,本篇博客承接之前的C语言进阶——数据结构之链表
的内容(没看过的小伙伴可以从我创建的专栏C语言进阶之数据结构 找到那篇文章并阅读后在回来哦~),上次我们重点说了链表中的单链表,即不带头单向不循环链表
还说到了链表的分类虽然有8种,但实际上最常用的还是单链表和双向链表(带头双向循环链表)
所以今天我们就来讲讲双向链表的实现吧~
双向链表的结构
下面是双向链表的一个图示:
双向链表,全称为带头双向循环链表
双向与循环这2个概念很好理解,所以我们下面看一下什么是带头
这个“带头”跟之前我们说的“头节点”是两个概念,
实际前面在说单链表时有称呼并不严谨,但是为了大家更好的理解就直接称为单链表的头节点
带头链表里的头节点,实际为“哨兵位”,哨兵位节点不存储任何有效元素,只是站在这里“放哨 的
哨兵位”存在的意义: 遍历循环链表避免死循环
对于双向链表的节点,我们这样定义:
typedef int LTDataType;
typedef struct ListNode
{
LTDataType data;
struct ListNode* next; //指针保存下一个节点的地址
struct ListNode* prev; //指针保存前一个节点的地址
}LTNode;
双向链表的实现
下面我们来实现一下双向链表的各个功能
其实当我们掌握了单链表的各个操作后,我们会发现其实双向链表虽然在结构上看着比单链表复杂不少,但在实现上并不难~
我们首先在VS上创建一个List的工程,再分别创建List.h头文件,List.c源文件以及Test.c测试文件,在这之上,我们依次去实现双向链表的各个功能~
初始化 LTInit
首先是初始化,因为双向链表多了一个头节点,即哨兵位,所以我们需要对其初始化~
代码如下:
LTNode* LTInit() //对哨兵位初始化~
{LTNode* phead = (LTNode*)malloc(sizeof(LTNode));if (phead == NULL) {perror("malloc fail!");exit(1);}phead->data = -1;phead->next =phead->prev =phead;return phead;}
下面来测试一下~
void ListTest()
{LTNode* plist = LTInit();}int main()
{ListTest();return 0;
}
这里我们通过调试来观察一下初始化是否成功:
另外,因为我们后面还要多次用到申请节点空间,所以我们单独封装一个函数LTBuyNode,
这样后面再使用只需要调用它就可以了
LTNode* LTBuyNode(LTDataType x) //申请新节点
{LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));if (newnode == NULL) {perror("malloc fail!");exit(1);}newnode->data = x;newnode->next = newnode->prev = newnode;return newnode;
}
同时,关于上面初始化的代码我们也可以进行简化:
LTNode* LTInit()
{LTNode* phead = LTBuyNode(-1);return phead;
}
尾插LTPushBack
好,有了这样一个链表,下面我们实现一下尾插LTPushBack
代码如下:
//尾插
void LTPushBack(LTNode* phead, LTDataType x)
{assert(phead); //phead不能为空LTNode* newnode = LTBuyNode(x);newnode->next = phead;newnode->prev = phead->prev;phead->prev->next = newnode;phead->prev = newnode;
}
同样,我们在Test.c文件中进行测试
void ListTest()
{LTNode* plist = LTInit();//尾插LTPushBack(plist, 1);LTPushBack(plist, 2);LTPushBack(plist, 3);LTPushBack(plist, 4);
}int main()
{ListTest();return 0;
}
调试后,,结果如下:
这样尾插的功能就实现了~
不过,我们后续如果一直用调试的方式去观察未免有些麻烦,所以这里我们也封装一个打印的函数
//打印
void LTPrint(LTNode* phead)
{//phead不能为空assert(phead);LTNode* pcur = phead->next;while (pcur != phead){printf("%d->", pcur->data);pcur = pcur->next;}}
有了打印函数,我们再测试尾插,只要运行代码就可以了
结果如下:
头插LTPushFront
接下来,我们来实现一下头插LTPushFront
关于头插,有一个需要注意的点,头插要插在第一个、有效节点之前,而不是在哨兵位之前
头插代码如下:
//头插
void LTPushFront(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newnode = LTBuyNode(x);//phead newnode phead->nextnewnode->next = phead->next;newnode->prev = phead;phead->next->prev = newnode;phead->next = newnode;
}
老规矩,写完后,我们来测试一下:
void ListTest()
{LTNode* plist = LTInit();//头插LTPushFront(plist, 1);LTPushFront(plist, 2);LTPushFront(plist, 3);LTPushFront(plist, 4);LTPrint(plist);}int main()
{ListTest();return 0;
}
尾删 LTPopBack
写删除操作时要注意:当链表为空时(只有一个哨兵位节点),要assert断言
代码如下:
void LTPopBack(LTNode* phead)
{assert(phead);//链表为空:只有一个哨兵位节点assert(phead->next != phead);LTNode* del = phead->prev;LTNode* prev = del->prev;prev->next = phead;phead->prev = prev;free(del);del = NULL;}
下面是测试代码以及结果:
void ListTest()
{LTNode* plist = LTInit();LTPushFront(plist, 1);LTPushFront(plist, 2);LTPushFront(plist, 3);LTPushFront(plist, 4);//尾删LTPopBack(plist);LTPrint(plist);printf("\n");LTPopBack(plist);LTPrint(plist);printf("\n");LTPopBack(plist);LTPrint(plist);}int main()
{ListTest();return 0;
}
头删LTPopFront
接下来我们来实现头部删除LTPopFront
直接上代码:
//头删
void LTPopFront(LTNode* phead)
{assert(phead);assert(phead->next != phead);LTNode* del = phead->next;LTNode* next = del->next;next->prev = phead;phead->next = next;free(del);del = NULL;
}
下面来测试:
void ListTest()
{LTNode* plist = LTInit();LTPushFront(plist, 1);LTPushFront(plist, 2);LTPushFront(plist, 3);LTPushFront(plist, 4);//头删LTPopFront(plist);LTPrint(plist);printf("\n");LTPopFront(plist);LTPrint(plist);printf("\n");LTPopFront(plist);LTPrint(plist);printf("\n");
}int main()
{ListTest();return 0;
}
运行结果如下:
查找LTFind
在前面我们已经实现了插入的4种操作,下面我们看一下查找
代码如下:
LTNode* LTFind(LTNode* phead, LTDataType x)//查找
{assert(phead);LTNode* pcur = phead->next;while (pcur != phead){if (pcur->data == x) return pcur;pcur = pcur->next;}return NULL;}
来测试一下吧~
void ListTest()
{LTNode* plist = LTInit();LTPushFront(plist, 1);LTPushFront(plist, 2);LTPushFront(plist, 3);LTPushFront(plist, 4);LTNode* findRet = LTFind(plist, 3);if (findRet == NULL) printf("未找到!\n");else printf("找到了!\n");
}int main()
{ListTest();return 0;
}
在指定位置之后插入数据LTInsert
插入代码如下:
//在pos位置之后插入数据
void LTInsert(LTNode* pos, LTDataType x)
{assert(pos);LTNode* newnode = LTBuyNode(x);newnode->next = pos->next;newnode->prev = pos;pos->next->prev = newnode;pos->next = newnode;
}
测试代码如下:
void ListTest()
{LTNode* plist = LTInit();LTPushFront(plist, 1);LTPushFront(plist, 2);LTPushFront(plist, 3);LTPushFront(plist, 4); //4->3->2->1->LTNode* findRet = LTFind(plist, 3);LTInsert(findRet,66); //预期结果为 //4->3->66->2->1->LTPrint(plist);}int main()
{ListTest();return 0;
}
运行结果:
删除pos位置的数据LTErase
删除代码如下:
//删除pos位置的数据
void LTErase(LTNode * pos)
{assert(pos);pos->next->prev = pos->prev;pos->prev->next = pos->next;}
下面我们来进行测试~
void ListTest()
{LTNode* plist = LTInit();LTPushFront(plist, 1);LTPushFront(plist, 2);LTPushFront(plist, 3);LTPushFront(plist, 4); //4->3->2->1->LTNode* findRet = LTFind(plist, 3);LTErase(findRet);LTPrint(plist); //预期结果为:4->2->1->
}int main()
{ListTest();return 0;
}
链表的销毁LTDestroy
最后我们看一下双向链表的销毁LTDestroy
注意:我们这里的函数要传的是地址,也就是要用到二级指针,因为这里我们直接要对链表的哨兵位做修改,要与前面的代码相区分哦~
销毁的代码如下:
void LTDesTroy(LTNode** pphead)
{assert(pphead);//哨兵位不能为空assert(*pphead);LTNode* pcur = (*pphead)->next;while (pcur != *pphead){LTNode* next = pcur->next;free(pcur);pcur = next;}//链表中只有一个哨兵位free(*pphead);*pphead = NULL;
}
至于销毁操作的调试,大家可以自行测试,这里就不再赘述了
到此,我们就把双向链表的操作给讲完了
事实上学会了单链表和双向链表的操作,即使将来遇到链表的其他6种类型也可以游刃有余,很快上手并解决问题的,所以建议大家还是要好好掌握单链表和双向链表的操作~
结语
好了,今天关于链表的分享就到这里了,如果对大家有帮助就太好啦~
在学习编程的道路上Humble与各位同行,加油吧各位!
最后,希望大家点个免费的赞或者关注吧(感谢感谢),也欢迎大家订阅我的专栏
让我们在接下来的时间里一起成长,一起进步吧!
相关文章:

C语言进阶——数据结构之链表(续)
前言 hello,大家好呀,我是Humble,本篇博客承接之前的C语言进阶——数据结构之链表 的内容(没看过的小伙伴可以从我创建的专栏C语言进阶之数据结构 找到那篇文章并阅读后在回来哦~),上次我们重点说了链表中…...

数据库课程设计-图书管理系统数据库设计
目录 一、实验目的 二、实验内容 三、实验要求 四、实验设计 4.1需求分析 4.1.1系统目标 4.1.2功能需求 4.1.3性能需求 4.14界面需求 4.2概念模型设计 4.2.1 实体及联系 4.2.2 E-R图 4.3 逻辑设计 4.3.1 E-R模型向关系模型的转换 4.3.2 数据库逻辑结构 4.3.3数据库模型函数依赖…...

【超简版,代码可用!】【0基础Python爬虫入门——下载歌曲/视频】
安装第三方模块— requests 完成图片操作后输入:pip install requests 科普: get:公开数据 post:加密 ,个人信息 进入某音乐网页,打开开发者工具F12 选择网络,再选择—>媒体——>获取URL【先完成刷新页面】 科…...

CommunityToolkit.Mvvm支持环境
引言 CommunityToolkit.Mvvm 包(又名 MVVM 工具包,以前称为 Microsoft.Toolkit.Mvvm)是一个现代、快速和模块化的 MVVM 库。 它是 .NET 社区工具包的一部分,其中一条原则是: 独立于平台和运行时 - .NET Standard 2.0…...

探讨品牌设计的本质,为企业形象注入活力!
品牌设计作为一个行业,首先需要明确行业的本质和意义。由于越来越多的咨询公司和营销公司对品牌有不同的理解和解释,因为他们服务的内容和专业水平不同,什么是品牌的定义越来越复杂,逐渐成为一种神秘的知识。例如,特劳…...

【Maven】-- 打包添加时间戳的两种方法
一、需求 在执行 mvn clean package -Dmaven.test.skiptrue 后,生成的 jar 包带有自定义系统时间。 二、实现 方法一:使用自带属性(不推荐) 使用系统时间戳,但有一个问题,就是默认使用 UTC0 的时区。举例…...

图片分类: 多类别
最近需要训练一个有200多类的图片分类网络,搜了一遍,发现居然没有很合适用的开源项目,于是自己简单撸了一个轮子,项目地址: https://github.com/xuduo35/imgcls_pytorch。支持如下backbone: alexnetresnet18,resnet34,resnet50,r…...

python 抓包tcp数据拷贝转发
在Python中,你可以使用scapy库进行抓包,使用shutil或io库进行数据的拷贝,以及使用socket库进行数据转发。下面是一个简单的示例,展示了如何进行这些操作: 首先,你需要安装必要的库。你可以使用pip来安装它…...

ubuntu 各版本图形界面和命令行切换快捷键介绍
文章目录 前言一、ubuntu 图形界面和命令行模式切换的快捷键1. ubuntu 16.042. ubuntu 18.043. ubuntu 20.044. ubuntu 22.04 总结 前言 本文主要介绍如何使用快捷键进行ubuntu 的图形界面和命令行模式切换,涉及如下 几个ubuntu 版本 ubuntu16.04 ubuntu18.04 ubun…...

基于SpringBoot Vue博物馆管理系统
大家好✌!我是Dwzun。很高兴你能来阅读我,我会陆续更新Java后端、前端、数据库、项目案例等相关知识点总结,还为大家分享优质的实战项目,本人在Java项目开发领域有多年的经验,陆续会更新更多优质的Java实战项目&#x…...

关于预检请求
基本概述 预检请求(Preflight Request)是一种由浏览器自动发起的请求,用于检查实际请求是否安全可行。这种请求通常在跨域请求(CORS)中出现,并且只在某些特定条件下触发。以下是触发预检请求的具体条件&am…...

cookie in selenium 定时更新token
1.selenium添加cookie访问 需要登录才能访问的链接 selenium 访问 “https://developer.org.com”,如果没登陆,则跳转到"https://console.org.com/login",此时selenium取到的cookie的domain是:.console.org.com。 而domain 是 .c…...

【MIdjourney】一些材质相关的关键词
1.多维剪纸(Multidimensional papercut) "Multidimensional papercut"(多维剪纸)是一种剪纸艺术形式,通过多层次的剪纸技巧和设计来创造出立体感和深度感。这种艺术形式通常涉及在不同的纸层上剪裁不同的图案,并将它们…...

递归组件怎么实现无线滚动
递归组件实现无限滚动的方法通常涉及到对数据的递归处理和组件的自我调用。以下是一个简单的示例,展示如何使用递归组件实现无限滚动: 首先,定义一个递归组件,该组件可以调用自己来渲染下一组数据。假设我们要展示一个滚动列表&a…...

致远OA如何开发 第十篇 数据库
数据库 此栏目技术支持 技术大佬对栏目文章的支持 特别感谢 如何编写dao实现数据的增删改查 新建文件 实现下面的方法即可,具体的sql操作需要自己组装 其中JDBCAgent 是致远封装过的工具Overridepublic void addData(String dataId, String agentId) {try (JDBC…...

信息检索与数据挖掘 | (十)线性回归与逻辑回归
文章目录 📚线性回归算法流程📚Bias and variance📚过拟合&欠拟合📚逻辑回归算法流程 📚线性回归算法流程 ybwx 使用loss function L来评估函数的好坏 从而我们要选择使L最小的模型参数w,b 使用梯度下降的方法…...

【issue-halcon例程学习】measure_arc.hdev
例程功能 检查倒角后铸件的细长孔之间的距离。 代码如下 read_image (Zeiss1, zeiss1) get_image_size (Zeiss1, Width, Height) dev_close_window () dev_open_window (0, 0, Width / 2, Height / 2, black, WindowHandle) set_display_font (WindowHandle, 14, mono, true,…...

RKE快速搭建离线k8s集群并用rancher管理界面
转载说明:如果您喜欢这篇文章并打算转载它,请私信作者取得授权。感谢您喜爱本文,请文明转载,谢谢。 本文记录使用RKE快速搭建一套k8s集群过程,使用的rancher老版本2.5.7(当前最新版为2.7)。适用…...

代码随想录算法训练营第十四天|● 理论基础 ● 递归遍历 ● 迭代遍历 ● 统一迭代
仅做学习笔记,详细请访问代码随想录 ● 理论基础 ● 递归遍历 ● 迭代遍历 ● 统一迭代 单层递归的逻辑就是按照中左右的顺序来处理的,这样二叉树的前序遍历,基本就写完了,再看一下完整代码: 前序遍历: …...

❤css实用
❤ css实用 渐变色边框(Gradient borders方法的汇总 5种) 给 border 设置渐变色是很常见的效果,实现这个效果有很多思路 1、使用 border-image 使用 css 的 border-image 属性给 border 绘制复杂图样 与 background-image 类似,我…...

web系统架构基于springCloud的各技术栈
博主目前开发的web系统架构是基于springCloud的一套微服务架构。 使用的技术栈:springbootmysqlclickhousepostgresqlredisrocketMqosseurekabase-gatewayapollodockernginxvue的一套web架构。 一、springboot3.0 特性:Spring Boot 3.0提供了许多新特性…...

【第十五课】数据结构:堆 (“堆”的介绍+主要操作 / acwing-838堆排序 / 时间复杂度的分析 / c++代码 )
目录 关于堆的一些知识的回顾 数据结构:堆的特点 "down" 和 "up":维护堆的性质 down up 数据结构:堆的主要操作 acwing-838堆排序 代码如下 时间复杂度分析 确实是在写的过程中频繁回顾了很多关于树的知识&…...

el-select选项过多导致页面卡顿,路由跳转卡顿
问题:el-select数据量太大,导致渲染过慢,或造成页面卡顿甚至于卡死 卡顿原因:DOM中数据过多,超过内存限制 解决方法: 1.使用Virtualized Select 虚拟化选择器,页面就不卡了 2.el-select做分…...

信息流广告参数回传工具怎么做联调
信息流广告在抖音等平台上越来越受到广告主的青睐,它能够在用户浏览内容的同时,以自然的方式展示广告,提高曝光率和点击率。然而,为了更好地评估广告效果,需要进行参数回传联调。本文将介绍一种实用的工具——数灵通外…...

matlab appdesigner系列-常用18-表格
表格,常用来导入外部表格数据 示例: 导入外界excel数据:data.xlsx 姓名年龄城市王一18长沙王二21上海王三56武汉王四47北京王五88成都王六23长春 操作步骤如下: 1)将表格拖拽到画布上 2)对app1右键进行…...

密码学的100个基本概念
密码学作为信息安全的基础,极为重要,本文分为上下两部分,总计10个章节,回顾了密码学的100个基本概念,供小伙伴们学习参考。本文将先介绍前五个章节的内容。 一、密码学历史 二、密码学基础 三、分组密码 四、序列密码 五、哈希…...

Python中的进制转换——bin/oct/hex函数与int函数
简介 进制转换可能是一个工作学习中的常见小任务,手写相关函数显然很麻烦。 Python有相关内置函数一般能满足我们的需求。bin()、oct()、hex()将十进制转换为常用的二、八、十六进制,而 int()函数可指定第二个参数从而将其它进制转换为十进制。或许后者…...

RT-Thread 瑞萨 智能家居网络开发:RA6M3 HMI Board 以太网+GUI技术实践
不用放大了, 我在包里找到张不小的…… 以太网HMI线下培训-环境准备 这是社群的文档:【腾讯文档】以太网线下培训(HMI-Board) https://docs.qq.com/doc/DY0FIWFVuTEpORlNn 先介绍周六的培训是啥,然后再介绍一下要准…...

力扣刷题第十天 美丽塔 一
给你一个长度为 n 下标从 0 开始的整数数组 maxHeights 。 你的任务是在坐标轴上建 n 座塔。第 i 座塔的下标为 i ,高度为 heights[i] 。 如果以下条件满足,我们称这些塔是 美丽 的: 1 < heights[i] < maxHeights[i]heights 是一个 山脉…...

c# ADODB.Recordset实例调用Fields报错
代码: using System; using System.CodeDom; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using ADODB;namespace ConsoleApp1 {internal class Programre{static ADODB.Recordset recordsetInstance…...