第五章:C语言数据结构与算法之双向带头循环链表
系列文章目录
文章目录
- 系列文章目录
- 前言
- 一、哨兵位的头节点
- 二、双向链表的结点
- 三、接口函数的实现
- 1、创建结点
- 2、初始化
- 3、尾插与尾删
- 4、头插与头删
- 5、打印
- 6、查找
- 7、随机插入与随机删除
- 8、判空、长度与销毁
- 四、顺序表和链表的对比
- 1. 不同点
- 2. 优缺点
- 五、缓存命中
- 1、缓存
- 2、缓存命中
- 总结
前言
一般题目给的单链表是无头单向非循环链表,但是我们可以升级成双向带头循环链表,这个链表比起单链表更有优势。
一、哨兵位的头节点

上面带有head头结点的链表就是带头的链表,题目中的链表一般没有头节点,phead指针直接指向第一个结点,而带头的链表phead指针指向头结点,头节点指向第一个结点,一般称为 哨兵位的头节点。
二、双向链表的结点
typedef int LTDataType;typedef struct ListNode
{struct ListNode* next;struct ListNode* prev;LTDataType data;
}LTNode;
比起单链表的结点,多了指向前一个结点的指针——prev。
三、接口函数的实现
1、创建结点
LTNode* BuyListNode(LTDataType x)
{LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));assert(newnode);newnode->next = NULL;newnode->prev = NULL;newnode->data = x;return newnode;}
2、初始化
LTNode* InitList()
{LTNode* phead = BuyListNode(-1);phead->next = phead;phead->prev = phead;return phead;
}
初始化即开辟一个头节点,然后让这个头节点的前后指针域都指向自己。
3、尾插与尾删

void LTPushBack(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newnode = BuyListNode(x); newnode->prev = phead->prev;phead->prev->next = newnode;newnode->next = phead;phead->prev = newnode;
}void LTPopBack(LTNode* phead)
{assert(phead);assert(phead->next != phead);//空phead->prev = phead->prev->prev;free(phead->prev->next);phead->prev->next = phead;}
双向带头循环链表并没有单独讨论空链表的情况,这就是头节点的好处,之所以不用讨论就是因为节点的个数不可能为0,最少也包括一个头节点。
4、头插与头删

void LTPushFront(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newnode = BuyListNode(x);LTNode* tail = phead->next;newnode->next = phead->next;newnode->prev = phead;tail->prev = newnode;phead->next = newnode;}void LTPopFront(LTNode* phead)
{assert(phead);assert(phead->next != phead);LTNode* tail = phead->next->next;LTNode* tailPrev = phead->next;phead->next = tail;tail->prev = phead;free(tailPrev);}
5、打印
void LTPrint(LTNode* phead)
{assert(phead);LTNode* cur = phead->next;while (cur != phead){printf("[%p | %d | %p]", cur->prev, cur->data, cur->next);if(cur->next != phead)printf("<->");cur = cur->next;}printf("\n");
}
就是从头遍历一遍即可,但是需要注意的是,这是一个循环链表,如果我们不加限制条件的话,他会一直循环下去。所以,我们这里需要加上判断条件。
6、查找
LTNode* LTFind(LTNode* phead, LTDataType x)
{assert(phead);assert(phead->next != phead);LTNode* cur = phead->next;while (cur->data != x && cur != phead)cur = cur->next;if (cur == phead)return NULL;else return cur;
}
也要加限制条件。
7、随机插入与随机删除
void* LTInsert(LTNode* pos, LTDataType x)
{assert(pos);LTNode* newnode = BuyListNode(x);LTNode* tail = pos->prev;tail->next = newnode;newnode->next = pos;newnode->prev = tail;pos->prev = newnode;
}void* LTErase(LTNode* pos)
{assert(pos);LTNode* tail = pos->prev;tail->next = pos->next;tail->next->prev = tail;free(pos);
}
实现方式之前的头尾操作一样,也可以复用到头尾操作中。
8、判空、长度与销毁
bool LTEmpty(LTNode* phead)
{assert(phead);return phead->next != phead;
}size_t LTSize(LTNode* phead)
{assert(phead);LTNode* cur = phead->next;size_t size = 0;while (cur != phead){size++;cur = cur->next;}return size;
}void LTDestory(LTNode* phead)
{LTNode* cur = phead->next;while (cur != phead)LTErase(cur);free(phead);
}
逐个释放就行。
四、顺序表和链表的对比
1. 不同点
| 不同点 | 顺序表 | 链表 |
|---|---|---|
| 存储空间上 | 物理上一定连续 | 逻辑上连续,但物理上不一定连续 |
| 随机访问 | 支持O(1) | 不支持:O(N) |
| 任意位置插入或者删除元素 | 可能需要搬移元素,效率低O(N) | 只需修改指针指向 |
| 插入 | 动态顺序表,空间不够时需要扩容 | 没有容量的概念 |
| 应用场景 | 元素高效存储+频繁访问 | 任意位置插入和删除频繁 |
| 缓存利用率 | 高 | 低 |
2. 优缺点
顺序表:
优点:尾插尾删效率高,下标的随机访问。
缺点:空间不够需要扩容(扩容的代价大);头部或者中间插入删除效率低,需要挪动数据。
链表:
优点:需要扩容,按需申请释放小块结点内存;任意位置插入效率很高–O(1)。
缺点:不支持下标随机访问;
五、缓存命中
1、缓存
CPU与内存经常有数据的访问与存储,但两者运行速度不同,就导致了CPU会“等待”内存传输数据的情况,我们在二者之间搭建一片缓冲区域,即缓存,来解决这个问题。

从下到上,各种存储器的内存逐渐降低,数据传输速度逐级增高。
2、缓存命中
那么每次CPU会从寄存器中读取数据,这二者的速度差距已经大大缩小了。我们以一个数组为例,我们想对第一个元素进行计算,我们不仅会把第一个元素所对的内存传输到寄存器,还会把其相邻的内存空间传输到寄存器中作为备用,每次传输到寄存器中的数据的大小取决于电脑的相应配置。
这样,我们在CPU访问完第一元素后,假设我们还需要计算第二个元素,我们又恰好在寄存器中存储了第二个元素的内存信息。CPU便可直接调用,而无需寄存器再去读取。这就叫缓存命中。
总结
链表和顺序表各有优势,带头双向链表比起单链表更加方便操作。
深窥自己的心,而后发觉一切的奇迹在你自己。——培根
相关文章:
第五章:C语言数据结构与算法之双向带头循环链表
系列文章目录 文章目录系列文章目录前言一、哨兵位的头节点二、双向链表的结点三、接口函数的实现1、创建结点2、初始化3、尾插与尾删4、头插与头删5、打印6、查找7、随机插入与随机删除8、判空、长度与销毁四、顺序表和链表的对比1. 不同点2. 优缺点五、缓存命中1、缓存2、缓存…...
一文带你了解,前端模块化那些事儿
文章目录前端模块化省流:chatGPT 总结一、参考资料二、发展历史1.无模块化引出的问题:横向拓展2.IIFE3.Commonjs(cjs)4.AMD引出的问题:5.CMD6.UMD7.ESM往期精彩文章前端模块化 省流:chatGPT 总结 该文章主要讲述了前端模块化的发展历史和各个…...
(六十五)大白话设计索引的时候,我们一般要考虑哪些因素呢?(中)
今天我们继续来说一下,在设计索引的时候要考虑哪些因素。之前已经说了,你设计的索引最好是让你的各个where、order by和group by后面跟的字段都是联合索引的最左侧开始的部分字段,这样他们都能用上索引。 但是在设计索引的时候还得考虑其他的…...
Spring事务管理
文章目录1 事务1.1 需求1.2 原因分析1.3 错误解决1.4 yml配置文件中开启事务管理日志1 事务 1.1 需求 当部门解散了不仅需要把部门信息删除了,还需要把该部门下的员工数据也删除了。可当在删除员工数据出现异常时,就不会执行删除员工操作,出…...
数字化工厂装配线生产管理看板系统
电力企业业务复杂,组织结构复杂,不同的业务数据,管理要求也不尽相同。生产管理看板系统针对制造企业的生产应用而开发,能够帮助企业建立一个规范准确即时的生产数据库。企业现状:1、计划不清晰:生产计划不能…...
vxe-grid 全局自定义filter过滤器,支持字典过滤
一、vxe-table的全局筛选器filters的实现 官网例子:https://vxetable.cn/#/table/renderer/filter 进入之后:我们可以参照例子自行实现,也可以下载它的源码,进行调整 下载好后并解压,用vscode将解压后的文件打开。全局…...
ECharts 环形图组件封装
一、ECharts引入1.安装echarts包npm install echarts --save2.引入echarts这里就演示全局引入了,挂载到vue全局,后面使用时,直接使用 $echartsimport * as echarts from echarts Vue.prototype.$echarts echarts二、写echarts组件这里演示环…...
c++ 怎么调用python 提供的函数接口
在 C 中调用 Python 函数有多种方法,以下是其中的两种常见方法:使用 Python/C APIPython 提供了 C/C API,可以通过该 API 在 C 中调用 Python 函数。使用这种方法,需要先将 Python 解释器嵌入到 C 代码中,然后可以通过…...
【动态规划】背包问题(01背包,完全背包)
Halo,这里是Ppeua。平时主要更新C语言,C,数据结构算法......感兴趣就关注我吧!你定不会失望。 🌈个人主页:主页链接 🌈算法专栏:专栏链接 我会一直往里填充内容哒! &…...
记录 UE5 完全重新构建 UE C++项目
不知道搞了什么,C项目的实时代码编译罢工了,搞了半天都修不好,只能又重建了 UE5 版本为 v5.1.1 删除以下文件夹 /Binaries /Intermediate /SavedBinaries 文件夹是编译后的模块 Intermediate 文件夹里是中间层的C代码,完全由ue…...
java版云HIS系统源码 微服务架构支持VUE
云his系统源码 一个好的HIS系统,要具有开放性,便于扩展升级,增加新的功能模块,支撑好医院的业务的拓展,而且可以反过来给医院赋能,最终向更多的患者提供更好地服务。 私信了解更多! 本套基于…...
苹果内购支付检验错误码
21000 The request to the App Store didn’t use the HTTP POST request method. 对App Store的请求没有使用HTTP POST请求方法。 21001 The App Store no longer sends this status code. App Store不再发送此状态代码。 21002 The data in the receipt-data property…...
day27_css
今日内容 上课同步视频:CuteN饕餮的个人空间_哔哩哔哩_bilibili 同步笔记沐沐霸的博客_CSDN博客-Java2301 零、 复习昨日 一、CSS 零、 复习昨日 见代码 一 、引言 1.1CSS概念 层叠样式表(英文全称:Cascading Style Sheets)是一种用来表现HTML(标准通…...
智慧赋能,聚力开源——第四届OpenI/O 启智开发者大会开源治理专场顺利举办!
为汇聚国内外知名开源组织共同探讨中国开源生态建设及开源治理相关议题,推进产学研用开源合作,2月24日下午,第四届OpenI/O启智开发者大会在深圳人才研修院智汇中心举办以“构建开源联合体,共建开源生态”为主题的开源治理专场分论…...
Java工程师应该如何成长?
近几年,不少开发者会抱怨“面试造火箭,天天拧螺丝”,每天进行重复业务开发,似乎能力被日常工作限制,无法突破提高。 极客时间《Java 核心技术 36 讲》专栏作者杨晓峰认为,如果处于新手阶段,全面…...
【数据分析师求职面试指南】必备编程技能整理之Hive SQL必备用法
文章目录熟悉Python懂R语言掌握SQL大数据基础数据库常用类型多表查询更多聚合函数distinctcase when窗口函数动态更新一行变多行调优内容整理自《拿下offer 数据分析师求职面试指南》—徐粼著 第四章编程技能考查其他内容:【数据分析师求职面试指南】必备基础知识整…...
Maven - Linux 服务器 Maven 环境安装与测试
目录 一.引言 二.安装流程 1.获取安装包 2.解压并安装 3.配置环境 4.mvn 验证 三.测试踩坑 1.Permission denied 2.Plugin or dependencies Error 一.引言 通道机上的 java 项目需要 mvn package 提示没有 mvn 命令,下面记录下安装 maven 的全过程。 二.安…...
5G模块可以注册到4G,不能注册到5G;SIM卡接到5G手机是可以注册到5G网络的?
5G网络覆盖范围较小或者信号质量不佳。在这种情况下,您可以尝试移动到不同的位置,以获得更好的信号质量和覆盖范围。 目前,5G网络已经在全球多个国家和地区推出,并且在不断扩大覆盖范围。以下是一些已经拥有5G覆盖的主要地区&…...
宝塔webhook自动化打包vue项目时,npm不生效问题
文章目录📋前言🎯查看webhook配置的代码🎯测试代码,检查输出内容🎯解决方法📋前言 这篇文章主要是记录和解决在宝塔面板中,webhook自动化打包vue项目时,npm不生效问题。说来奇怪&am…...
嵌入式 Linux进程间通信之信号量
目录 一、信号量 1、信号量概述 2、什么是信号量 3、信号量的分类 4、进程获取共享资源要执行的操作 5、System V IPC 机制:信号量 5.1 semget函数 5.2 semop函数 5.3 semctl函数 一、信号量 1、信号量概述 信号量集:由若干个信号组成的集合&a…...
eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...
[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.
ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #:…...
Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...
