【数据结构】双向链表(Doubly Linked List)

双向链表(Doubly Linked List)是一种链式数据结构,它的每个节点都包含三个部分:数据、指向前一个节点的指针(prev),以及指向下一个节点的指针(next)。与单向链表不同,双向链表允许从任意节点向前或向后遍历,提供了更灵活的操作方式。

双向链表的结构

双向链表的每个节点都有以下三个部分:

  1. 数据部分:存储节点中的实际数据。
  2. 前向指针 (prev):指向当前节点的前一个节点,头节点的 prevnullptr
  3. 后向指针 (next):指向当前节点的下一个节点,尾节点的 nextnullptr

这种双指针的结构允许我们高效地在链表中进行插入、删除等操作。

双向链表的操作

  1. 插入操作:在双向链表中插入一个新节点时,需要更新前后两个节点的指针,因此插入操作比单向链表略复杂,但仍然能在 O(1) 时间内完成(假设已经找到插入点)。
  2. 删除操作:删除一个节点时,需要修改前后节点的指针,也需要处理边界条件,如删除头节点或尾节点。
  3. 遍历操作:可以从任意节点开始,向前或向后遍历链表。

C++ 实现

下面是一个简单的 C++ 双向链表实现,包含插入、删除、遍历等常用操作。

#include <iostream>struct Node {int data;Node* prev;Node* next;// 构造函数Node(int value) : data(value), prev(nullptr), next(nullptr) {}
};class DoublyLinkedList {
private:Node* head;public:// 构造函数初始化空链表DoublyLinkedList() : head(nullptr) {}// 在链表头插入新节点void insertAtHead(int value) {Node* newNode = new Node(value);if (head != nullptr) {newNode->next = head;head->prev = newNode;}head = newNode;}// 在链表尾插入新节点void insertAtTail(int value) {Node* newNode = new Node(value);if (head == nullptr) {head = newNode;return;}Node* temp = head;while (temp->next != nullptr) {temp = temp->next;}temp->next = newNode;newNode->prev = temp;}// 删除指定值的节点void deleteNode(int value) {Node* temp = head;while (temp != nullptr && temp->data != value) {temp = temp->next;}if (temp == nullptr) {std::cout << "Node with value " << value << " not found.\n";return;}if (temp->prev != nullptr) {temp->prev->next = temp->next;} else {head = temp->next;}if (temp->next != nullptr) {temp->next->prev = temp->prev;}delete temp;}// 正向遍历链表void traverseForward() {Node* temp = head;while (temp != nullptr) {std::cout << temp->data << " ";temp = temp->next;}std::cout << std::endl;}// 反向遍历链表void traverseBackward() {if (head == nullptr) return;Node* temp = head;while (temp->next != nullptr) {temp = temp->next;}while (temp != nullptr) {std::cout << temp->data << " ";temp = temp->prev;}std::cout << std::endl;}// 析构函数:释放内存~DoublyLinkedList() {Node* temp = head;while (temp != nullptr) {Node* next = temp->next;delete temp;temp = next;}}
};int main() {DoublyLinkedList dll;dll.insertAtHead(10);dll.insertAtHead(20);dll.insertAtTail(30);dll.insertAtTail(40);std::cout << "Forward traversal: ";dll.traverseForward(); // 输出: 20 10 30 40std::cout << "Backward traversal: ";dll.traverseBackward(); // 输出: 40 30 10 20dll.deleteNode(10);std::cout << "After deleting 10, forward traversal: ";dll.traverseForward(); // 输出: 20 30 40return 0;
}

代码说明

  1. Node 结构体:每个节点包含 dataprevnext 三个成员变量,用于存储节点的数据和链表的双向连接。
  2. DoublyLinkedList
    • insertAtHead:在链表头插入节点,注意要更新新头节点和原头节点的指针。
    • insertAtTail:遍历链表到末尾,然后在尾部插入节点。
    • deleteNode:找到目标节点,修改前后节点的指针,使链表跳过该节点。
    • traverseForwardtraverseBackward:分别用于正向和反向遍历链表。
  3. 内存管理:链表析构函数会遍历链表并释放所有节点,避免内存泄漏。

应用场景

双向链表广泛应用于需要双向遍历或频繁插入、删除操作的场景,比如:

  • 浏览器历史记录:允许用户前进和后退浏览网页。
  • 音乐播放列表:可以向前或向后切换歌曲。
  • 内存管理:操作系统的内存块分配常常使用双向链表进行管理。

通过使用双向链表,可以提高程序处理数据的灵活性和效率。在 C++ 中实现双向链表,既考验了对指针操作的掌握,也有助于理解动态数据结构的原理。

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

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

相关文章

基于Vue的汽车维修配件综合管理系统设计与实现SpringBoot后端源码

目录 1. 系统背景 2. 系统目标 3. 功能模块 4. 技术选型 5. 关键技术点 6. 实现步骤 7. 项目意义 8. 后期展望 1. 系统背景 市场需求分析&#xff1a;随着汽车保有量的不断增加&#xff0c;汽车维修和保养的需求日益增长。车主对维修质量和配件质量的要求也越来越高。汽…

class 004 选择 冒泡 插入排序

我感觉这个真是没有什么好讲的, 这个是比较简单的, 感觉没有什么必要写一篇博客, 而且这个这么简单的排序问题肯定有人已经有写好的帖子了, 肯定写的比我好, 所以我推荐大家直接去看“左程云”老师的讲解就很好了, 一定是能看懂的, 要是用文字形式再写一遍, 反而有点画蛇添足了…

java中有两个list列表,尽量少的去循环

java中有两个list列表&#xff0c;一个list列表是paymentRecord&#xff0c;另外一个list是listApplyBase&#xff0c;paymentRecord中的lendCode字段值跟listApplyBase中的repaymentCode字段值是对应的&#xff0c;用stream流去循环paymentRecord列表&#xff0c;然后判断当pa…

javascript中如何实现继承(附案例)

在 JavaScript 中&#xff0c;有多种实现继承的方法&#xff0c;最常用的有原型链继承、构造函数继承、组合继承和 class 继承&#xff08;ES6&#xff09;。下面以 ES6 的 class 继承为例&#xff0c;展示如何实现继承&#xff1a; 示例&#xff1a; // 父类 class Animal {…

React响应式数据useState

React响应式数据useState 最近学了React&#xff0c;发现与Vue大有不同&#xff0c;在Vue中实现数据的响应式通过ref()函数&#xff0c;React则是通过useState()函数 使用 语法&#xff1a;const [data, setData] useState(数据) 说明&#xff1a;将数据传给useState()&am…

CANoe_TestModule截图功能TestReportAddWindowCapture

前言 TestReportAddWindowCapture方法作为CAPL脚本中的一个重要功能&#xff0c;其能够将指定窗口的屏幕截图添加到测试报告中&#xff0c;对于记录和验证界面状态具有重要意义。本文将全面解析TestReportAddWindowCapture方法的使用方法、参数解释、示例应用以及注意事项&…

中小企业做网站需要考虑哪些因素?

中小企业在建设网站时&#xff0c;需要考虑的因素有很多。以下是一些主要考虑因素的介绍&#xff1a; 明确建站目的&#xff1a;中小企业需要明确自己建立网站的目的。是为了展示企业形象、推广产品&#xff0c;还是提供客户服务&#xff1f;不同的目的将决定网站的设计和功能…

R语言的下载、安装及环境配置(RstudioVSCode)

0x01 R语言篇 一、软件介绍 R for Windows是一个免费的用于统计计算和统计制图的优秀工具&#xff0c;是R语言开发工具。它拥有数据存储和处理系统、数组运算工具&#xff08;其向量、矩阵运算方面功能尤其强大&#xff09;、完整连贯的统计分析工具、优秀的统计制图等功能。…

2.创建第一个MySQL存储过程(2/10)

引言 在现代数据库管理中&#xff0c;存储过程扮演着至关重要的角色。它们是一组为了执行特定任务而编写的SQL语句集合&#xff0c;这些语句被保存在数据库中&#xff0c;并且可以被多次调用执行。存储过程不仅可以提高数据库操作的效率&#xff0c;还能增强数据的安全性和一致…

2-113 基于matlab的图像的配准融合

基于matlab的图像的配准融合&#xff0c;采用互信息配准&#xff0c;PV差值&#xff0c;powell算法&#xff0c;小波变换的图像融合算法。在GUI界面输入两幅图像&#xff0c;完成图像的配准融合。融合图像要求像素 一样。程序代码已经有详细的注释。程序已调通&#xff0c;可直…

多个单链表的合成

建立两个非递减有序单链表&#xff0c;然后合并成一个非递增有序的单链表。 注意&#xff1a;建立非递减有序的单链表&#xff0c;需要采用创建单链表的算法 输入格式: 1 9 5 7 3 0 2 8 4 6 0 输出格式: 9 8 7 6 5 4 3 2 1 输入样例: 在这里给出一组输入。例如&#xf…

鸿蒙harmonyos next纯flutter开发环境搭建

公司app是用纯flutter开发的&#xff0c;目前支持android和iOS&#xff0c;后续估计也会支持鸿蒙harmonyos。目前谷歌flutter并没有支持咱们国产手机操作系统鸿蒙harmonyos&#xff0c;于是乎国内有个叫OpenHarmony-SIG的组织&#xff0c;去做了鸿蒙harmonyos适配flutter开发的…

ROS无人机机械爪使用

引言&#xff1a;使用飞控的主通道5-8作为舵机控制输出&#xff0c;需要提前设置好飞控参数&#xff0c;否则无效。本节资料文件尚未整理完毕&#xff0c;整理完毕后会在B站进行视频讲解&#xff0c;并进行开源 1、启动mavros通信&#xff0c;用于订阅遥控器的按键信息&#x…

harbor https配置

安装docker compose curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo yum -y install docker-compose docker-compose version生成自建CA证书 生成CA私钥&#xff1a; openssl genrsa -out /path/ca/ca.key 4096生成ca的自签名证书: open…

【力扣 | SQL题 | 每日四题】力扣1783,1757,1747,1623,1468,1661

昨天晚上睡着了&#xff0c;今天把昨天的每日一题给补上。 1. 力扣1783&#xff1a;大满贯数量 1.1 题目&#xff1a; 表&#xff1a;Players ------------------------- | Column Name | Type | ------------------------- | player_id | int | | player_na…

【AI知识点】词嵌入(Word Embedding)

词嵌入&#xff08;Word Embedding&#xff09;是自然语言处理&#xff08;NLP&#xff09;中的一种技术&#xff0c;用于将词语或短语映射为具有固定维度的实数向量。这些向量&#xff08;嵌入向量&#xff09;能够捕捉词语之间的语义相似性&#xff0c;即将语义相近的词映射到…

oracle 新建用户,用户插入数据报错:ORA-01950: 对表空间 ‘USERS‘ 无权限

oracle 新建用户&#xff0c;用户插入数据报错:ORA-01950: 对表空间 ‘USERS’ 无权限 根据业务需求创建了一个新的表空间和一个新的用户&#xff0c;当用这个新用户创建表时&#xff0c;报错&#xff1a;ORA-01950: 表空 间’USERS’中无权限。我已经把创建表的权限赋给了此用…

使用SpringBoot自定义注解+拦截器+token机制,实现接口的幂等性

1 整合springboot和redis环境的集成2 配置请求的方法体和枚举类 import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;Data AllArgsConstructor NoArgsConstructor public class Response {private int status;private String msg;privat…

LeetCode hot100---链表专题(C++语言)

1、相交链表 &#xff08;1&#xff09;题目描述以及输入输出 (1)题目描述: 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交点&#xff0c;返回 null 。 (2)输入输出描述&#xff1a; 输入&#xff1a;…

【游戏模组】重返德军总部2009高清重置MOD,建模和材质全部重置,并且支持光追效果,游戏画质大提升

各位好&#xff0c;今天小编给大家带来一款新的高清重置MOD&#xff0c;本次高清重置的游戏叫《重返德军总部2009》2009年发布&#xff0c;我相信很多玩家已经玩过了&#xff0c;如果你还没有玩过我也可以和你简单介绍一下剧情&#xff0c;这款游戏故事背景接续在《重返德军总部…