数据结构入门 — 链表详解_双向链表

前言

数据结构入门 — 双向链表详解*
博客主页链接:https://blog.csdn.net/m0_74014525
关注博主,后期持续更新系列文章
文章末尾有源码
*****感谢观看,希望对你有所帮助*****


系列文章

第一篇:数据结构入门 — 链表详解_单链表
第二篇:数据结构入门 — 链表详解_双向链表
第三篇:数据结构入门 — 链表详解_循环链表


文章目录

  • 前言
  • 系列文章
  • 什么是双向链表
  • 概念与结构(图文)
  • 双向链表与单链表的区别
  • 带头双向循环链表接口实现(代码演示)
    • 1. 动态存储结构
    • 双向链表打印
    • 增删查改接口
    • 双向链表销毁
  • 五、所有文件代码
    • 1. Gitee链接
  • 总结


什么是双向链表

双向链表(Doubly Linked List)是一种链表数据结构,它的每个节点都含有两个指针,一个指向前一个节点,一个指向后一个节点。相比较于单向链表,双向链表可以双向遍历,即可以从头到尾或从尾到头遍历链表。在双向链表中,每个节点包含两个指针域和一个数据域。其中,一个指针指向前驱节点,另一个指针指向后继节点。这两个指针使得双向链表的插入、删除等操作不需要像单向链表那样需要遍历整个链表来寻找前驱节点,提高了链表的操作效率。

概念与结构(图文)

在这里插入图片描述
带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了,后面我们代码实现了就知道了。

双向链表与单链表的区别

双向链表和单链表是两种不同的链表结构。

单向链表是一种链表,在每个节点中包含指向下一个节点的指针。这意味着在单向链表中,节点只能从头开始遍历到尾部。在单向链表中,每个节点只存储指向下一个节点的指针,而不存储指向前一个节点的指针。

双向链表是一种链表,在每个节点中包含指向下一个节点和前一个节点的指针。这意味着在双向链表中,节点可以被从头到尾或从尾到头遍历。在双向链表中,每个节点存储指向前一个节点和下一个节点的指针。

因此,双向链表可以更方便地进行双向遍历,但是需要更多的内存空间来存储每个节点的两个指针。相比之下,在单向链表中,只需要一个指针来指向下一个节点,因此内存占用量更小。

带头双向循环链表接口实现(代码演示)

带头+双向+循环链表增删查改实现

1. 动态存储结构

typedef int STDataType;
typedef struct ListNode
{struct ListNode* prev;struct ListNode* next;STDataType data;
}LTNode;

双向链表打印

void LTPrint(LTNode* phead)
{assert(phead);printf("phead<->");//跳过哨兵位LTNode* cur = phead->next;while (cur != phead){printf("%d<->", cur->data);cur = cur->next;}printf("\n");
}

增删查改接口

根据增删查改顺序编排
双向链表头插:

//头插
void  LTPushFront(LTNode* phead, STDataType x)
{assert(phead);LTNode* newnode = BuyLTNode(x);LTNode* first = phead->next;newnode->next = first;first->prev = newnode;phead->next = newnode;newnode->prev = phead;}

双向链表尾插:

//尾插
void LTPushBack(LTNode* phead, STDataType x)
{assert(phead);LTNode* newnode = BuyLTNode(x);//找到最后一个LTNode* tail = phead->prev;newnode->prev = tail;tail->next = newnode;newnode->next = phead;phead->prev = newnode;
}

双向链表头删:

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

双向链表尾删:

//尾删
void LTPopBack(LTNode* phead)
{assert(phead);assert(phead->next != phead);LTNode* tail = phead->prev;LTNode* tailprev = tail->prev;free(tail);phead->prev = tailprev;tailprev->next = phead;}

查找:

LTNode* LTFind(LTNode* phead, STDataType x)
{assert(phead);LTNode* cur = phead->next;while (cur != phead){if (cur->data == x){return cur;}cur = cur->next;}return NULL;
}

在指点位置插入:

void LTInsert(LTNode* pos, STDataType x)
{LTNode* newnode = BuyLTNode(x);LTNode* posprev = pos->prev;newnode->next = pos;pos->prev = newnode;posprev->next = newnode;newnode->prev = posprev;}

在指点位置删除:

// 把pos删除
void LTErase(LTNode* pos)
{LTNode* posprev = pos->prev;LTNode* posnext = pos->next;free(pos);posprev->next = posnext;posnext->prev = posprev;
}

双向链表销毁

void LTDestory(LTNode* phead)
{LTNode* cur = phead->next;while (cur != phead){LTNode* next = cur->next;free(cur);cur = next;}free(phead);phead = NULL;
}

五、所有文件代码

1. Gitee链接

***查看所有代码***
点击右边蓝色文字 DuckBro Gitee 代码仓库


总结

带头双向循环链表的基本概念和常见操作。带头双向循环链表是一种特殊的双向链表,它多了一个头节点和一个尾节点,并且首尾相连形成一个环。

这样可以实现循环遍历链表。在带头双向循环链表中,插入、删除节点等操作都有特殊处理方式。带头双向循环链表在实际应用中比较常见,如操作系统中的进程管理、音乐播放器中的播放列表等。


如这篇博客对大家有帮助的话,希望 三连 支持一下 !!! 如果有错误感谢大佬的斧正 如有 其他见解发到评论区,一起学习 一起进步。

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

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

相关文章

【GeoDa实用技巧100例】025:geoda空间回归分析案例教程

严重声明:本文来自专栏《GeoDa空间计量案例教程100例》,为CSDN博客专家刘一哥GIS原创,原文及专栏地址为:https://blog.csdn.net/lucky51222/category_12373659.html,谢绝转载或爬取!!! 文章目录 一、空间自回归模型二、Geoda空间回归分析普通最小二乘法回归(OLS)空间…

【算法】探讨1+1中的深刻含义

一、引言 介绍11的基本含义和历史背景 11是数学中最基本的算术运算之一&#xff0c;代表着两个数的加法。这个公式可以追溯到古代数学&#xff0c;最早可以追溯到古埃及的数学文献。在古代数学中&#xff0c;112是最基本的加法运算&#xff0c;被广泛应用于各种数学问题中。 …

原生js插入HTML元素

原生js插入HTML元素方法&#xff1a;insertAdjacentHTML insertAdjacentHTML语法格式 element.insertAdjacentHTML(position, text); 1&#xff09;position 是相对于 element 元素的位置&#xff0c;并且只能是以下的字符串之一&#xff1a; 1.beforebegin&#xff1a;在 ele…

算法 位运算

文章目录 一、&&#xff08;按位与&#xff09;运算符二、|&#xff08;按位或&#xff09;运算符三、^&#xff08;异或&#xff09;运算符四、~&#xff08;取反&#xff09;运算符五、<<&#xff08;左移&#xff09;运算符六、>>&#xff08;右移&#xff…

Linux安装Redis数据库,无需公网IP实现远程连接

文章目录 1. Linux(centos8)安装redis数据库2. 配置redis数据库3. 内网穿透3.1 安装cpolar内网穿透3.2 创建隧道映射本地端口 4. 配置固定TCP端口地址4.1 保留一个固定tcp地址4.2 配置固定TCP地址4.3 使用固定的tcp地址连接 Redis作为一款高速缓存的key value键值对的数据库,在…

【Vue】vue2项目使用swiper轮播图2023年8月21日实战保姆级教程

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、npm 下载swiper二、使用步骤1.引入库声明变量2.编写页面3.执行js 总结 前言 swiper轮播图官网 参考文章&#xff0c;最好先看完他的介绍&#xff0c;再看…

WPF中的数据转换-StringFormat

WPF中的数据转换-StringFormat 前言 字符串格式化。使用该功能可以通过设置Binding.StringFormat属性对文本形式的数据进行转换——例如包含日期和数字的字符串。对于至少一半的格式化任务&#xff0c;字符串格式化是一种便捷的技术。 使用 当设置Binding.StringFormat属性…

基于微信小程序的餐厅预订系统的设计与实现(论文+源码)_kaic

摘 要 随着消费升级&#xff0c;越来越多的年轻人已经开始不再看重餐饮等行业的服务&#xff0c;而是追求一种轻松自在的用餐、购物环境。因此&#xff0c;无人餐厅、无人便利店、无人超市等一些科技消费场所应势而生。餐饮企业用工荒已成为不争的事实。服务员行业的低保障、低…

Centos开启防火墙和端口命令

Centos开启防火墙和端口命令 1. 开启查看关闭firewalld服务状态2. 查看端口是否开放3. 新增开放端口4. 查看开放的端口 1. 开启查看关闭firewalld服务状态 #启动/关闭firewall systemctl start/stop firewalld #查看防火墙状态 systemctl status firewalld #禁用或者启用 syst…

pytorch 实现VGG

VGG全称是Visual Geometry Group&#xff0c;因为是由Oxford的Visual Geometry Group提出的。AlexNet问世之后&#xff0c;很多学者通过改进AlexNet的网络结构来提高自己的准确率&#xff0c;主要有两个方向&#xff1a;小卷积核和多尺度。而VGG的作者们则选择了另外一个方向&a…

九五从零开始的运维之路(其三十六)

文章目录 前言一、集群概述1.负载均衡技术类型&#xff08;一&#xff09;四层负载均衡器&#xff08;二&#xff09;七层负载均衡器 2.负载均衡实现方式&#xff08;一&#xff09;硬件负载均衡产品&#xff1a;&#xff08;二&#xff09;软件负载均衡产品&#xff1a; 二、L…

[蓝帽杯 2022 初赛]domainhacker

打开流量包&#xff0c;追踪TCP流&#xff0c;看到一串url编码 放到瑞士军刀里面解密 最下面这一串会觉得像base64编码 删掉前面两个字符就可以base64解码 依次类推&#xff0c;提取到第13个流&#xff0c;得到一串编码其中里面有密码 导出http对象 发现最后有个1.rar文件 不出…

Vue使用ffmpeg,报ReferenceError: SharedArrayBuffer is not defined 如何解决

“SharedArrayBuffer is not defined” 错误是因为在浏览器环境中&#xff0c;SharedArrayBuffer 对象被认为是一种潜在的安全风险。为了防止 Spectre 攻击等漏洞&#xff0c;现代浏览器通常会禁用或限制对 SharedArrayBuffer 的使用。 SharedArrayBuffer 是一种 JavaScript 对…

前端面试:【代码质量与工程实践】单元测试、集成测试和持续集成

在现代软件开发中&#xff0c;确保代码质量是至关重要的。单元测试、集成测试和持续集成是关键的工程实践&#xff0c;用于提高代码的可靠性和可维护性。本文将深入探讨这些概念&#xff0c;以及它们如何在软件开发中发挥作用。 1. 单元测试&#xff08;Unit Testing&#xff0…

SpringBoot案例-登录校验-概述

登录存在的问题 在未登录的情况下&#xff0c;我们也可以直接访问部门管理、员工管理等功能由于Http协议是无状态的&#xff0c;即每次请求都是独立的&#xff0c;下一次的请求不会携带上一次的数据&#xff0c;服务器无法判断是否已经登录。 登录校验 如何实现登录校验 在员…

Agile Iteration Velocity

【agile iteration velocity】敏捷速度指的平均速度 第四次迭代结束速度&#xff1a; 76 / 4 19 第五次迭代结束速度&#xff1a; &#xff08;76 24 &#xff09; / 5 100 / 5 20

spark第四课

countByValue 数据源中相同的值有多少个,也就是WordCount countByKey 表的是键值对中的key出现了几次,与Value的值无关 不推荐collect,因为他是将数据放入内存,但是内存不够大的话,就容易崩,所以使用saveAsTextFile更好,直接放入磁盘. 保存成对象文件,需要序列化 启动了2个 J…

【Spring Boot】社交网站中验证用户登录的checkUser方法

public boolean checkUser(User user) {User userInDb userRepository.findByUsername(user.getUsername());if (userInDb ! null && userInDb.getPassword().equals(user.getPassword())) {return true;} else {return false;}} } 这段代码是UserService类中的checkU…

并查集(种类并查集,带权并查集)

链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 题目描述 动物王国中有三类动物A,B,C&#xff0c;这三类动物的食物链构成了有趣的环形。A吃B&#xff0c;B吃C&#xff0c;C吃A。 现有N个动物&#xff0c;以1&#xff0d;N编号。每个动物都…

C++有向、无向完全图的边数

一、无向完全图 一个拥有n个结点的无向完全图的边数为&#xff1a; 公式&#xff1a; 简写&#xff1a; &#xff08;表示个顶点中有条边&#xff09; 具体的解释&#xff1a; 比如我们有一个拥有个结点的无向完全图 我们首尾依次连接&#xff0c;共有条边。 然后我们选择…