【数据结构】轻松创造一个自己的双向链表

设计之美-链表与队列 数据结构概述随着计算机科学的发展,人们在计算机的各个领域创造了许多前所唯有的东西,在软件领域,在追求算法效率的同时与其紧密相连的就是数据结构。好的数据结构不仅可以有效的管理计算机中的所有数据,同时还能为为算法的设计上提供了许多意想不到的好处,因此许多高效的算法都是依赖其特定的数据结构对所操纵的数据进行组织的。即使现如今计算机硬件仍然遵循摩尔定律在高速发展着,但人类的需求总是大于硬件发展所能提供的性能 阅读详情

双向链表

双向链表应用实例,双向链表的操作分析和实现

管理单向链表的缺点分析:

  1. 单向链表,查找的方向只能是一个方向,而双向链表可以向前或者向后查找。

  2. 向链表不能自我删除,需要靠辅助节点 ,而双向链表,则可以自我删除,所以前面我们单链表删除 时节点,总是找到 temp,temp 是待删除节点的前一个节点(认真体会).

  3. 分析了双向链表如何完成遍历,添加,修改和删除的思路

双向链表实现思路

image-20211223000703533

分析 双向链表的遍历,添加,修改,删除的操作思路===》代码实现

  1. 遍历 方和 单链表一样,只是可以向前,也可以向后查找
  2. 添加 (默认添加到双向链表的最后)
    1. (1) 先找到双向链表的最后这个节点
    2. (2) temp.next = newHeroNode
  1. newHeroNode.pre = temp;

  2. 修改 思路和 原来的单向链表一样. 4) 删除

    (1) 因为是双向链表,因此,我们可以实现自我删除某个节点

    (2) 直接找到要删除的这个节点,比如 temp

    (3) temp.pre.next = temp.next

    (4) temp.next.pre = temp.pre;

实现链表节点

/**
 * 双向链表要用的节点
 * */
class ListNode {
    //排名
    public int No;
    // 姓名
    public String Name;
    //昵称
    public String NickName;
    // 下一个节点
    public ListNode next;
    //上一个节点
    public ListNode pre;

    public ListNode(int hNo, String hName, String hNickName) {
        this.No = hNo;
        this.Name = hName;
        this.NickName = hNickName;
    }

    //方便输出语句输出
    @Override
    public String toString() {
        return "HeroNode{" +
                "No=" + No +
                ", Name='" + Name + '\'' +
                ", NickName='" + NickName + '\'' +
                '}';
    }
}

双向链表实现

class DoubleLinkedList {
    //创建一个头结点
    ListNode head = new ListNode(0, "", "");

    public ListNode getHead() {
        return head;
    }

    public void setHead(ListNode head) {
        this.head = head;
    }

    //遍历链表
    public void List() {
        if (head.next == null) {
            System.out.println("链表为空");
            return;
        }
        //头节点不能动 这里我们用一个临时指针来记录
        ListNode temp = head.next;
        while (true) {
            //遍历为空就代表找了最后一个节点
            if (temp == null) {
                break;
            }
            //输出节点
            System.out.println(temp);
            //后移一位
            temp = temp.next;
        }
    }

    //加入双向链表
    public void add(ListNode node) {
        //头节点不能动 这里我们用一个临时指针来记录
        ListNode temp = head;
        //遍历链表
        while (true) {
            //遍历为空就代表找了最后一个节点
            //不为空就后移一位继续找
            if (temp.next == null) {
                break;
            }
            //没有找到最后就后移 temp
            temp = temp.next;
        }
        //指向下一个节点
        temp.next = node;
        //指向上一个节点
        node.pre = temp;
    }

    //修改双向链表,和单向链表基本一致不需要过多的修改
    //修改节点信息
    public void updateNode(ListNode newlistnode) {
        if (head.next == null) {
            System.out.println("链表是空的");
        }
        //这里是头节点不能修改,我用 temp 来指向头结点
        ListNode temp = head.next;
        // 是否找到了no的标识
        boolean flag = false;
        while (true) {
            //找到最后一个
            if (temp == null) {
                break;
            }
            if (temp.No == newlistnode.No) {
                //如果等于 那么代表可以修改
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if (flag) {
            //  true 修改信息
            temp.NickName = newlistnode.NickName;
            temp.Name = newlistnode.Name;
        } else {
            System.out.printf("没有找到 %d 这个节点", newlistnode.No);
        }
    }

    /*
     * 双向链表删除
     * 对于双向链表来说就不需要找到上一个节点来删除了,
     * 可以找到自己删除
     * */
    public void DeleteNode(int no) {
        if (head.next == null) {
            System.out.println("链表为空 不需要删除");
            return;
        }
        ListNode temp = head.next;
        // 用来标注 是不是可以删除
        boolean flag = false;
        while (true) {
            if (temp == null) {
                break;
            }
            if (temp.next.No == no) {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        //根据flag 删除Node
        if (flag) {
            //找到的话就删除,这里我们只需要指向空 GC会回收
            //temp.next = temp.next.next; 原先的单向链表删除现在在双向链表里就不好使了
            /*将当前节点的上一个节点的下一个指向 指向当前节点的下一个节点 相当于向前指向的next 直接跨过当前的节点指向下一个节点*/
            temp.pre.next = temp.next;
            /*将当前节点的下一个节点的上一个指向 指向当前节点的上一个节点,相当于向前的pre 直接快过当前的节点指向上一个
             * 如果当前节点是最后一节点,就不执行后面这个将下一个节点的指向更改,不然会出现空指针
             * */
            if (temp.next != null) {
                temp.next.pre = temp.pre;
            }
            /*这两步 坐完相当于 此时的当前节点已经没有了指向 会被回收*/
        } else {
            System.out.printf("要删除的 %d 没有找到", no);
        }
    }
}

效果

在这里插入图片描述

总结

双向链表在之前的基础上:

  1. 对比单向链表 双向链表可以自己删除,
  2. 双线链表正反遍历更加的容易
深度排查:网讯网卡WX1860AL4千兆网口降速百兆的硬件陷阱 本文详细剖析了网讯网卡WX1860AL4千兆网口降速至百兆的硬件故障排查过程。通过分析千兆以太网硬件原理,提供从网线、供电到PCB走线、焊接残留的标准化检修流程,并分享两种典型硬件陷阱(线序错误与焊锡短路)的实战修复案例,为硬件工程师解决类似传输速率问题提供系统性的诊断思路与方法。 阅读详情

相关推荐

ST-LINK调试STM32H743必看:CubeMX工程中缺失的这行代码导致程序跑飞

本文深入剖析了使用ST-LINK调试STM32H743时,因CubeMX工程中缺失电源电压档位配置代码而导致程序跑飞或出现“Can not access memory”错误的问题。文章解释了H7系列电源与时钟耦合的核心原理,提供了具体的代码修复方案和系统化的调试排查思路,帮助开发者从根本上解决这一常见调试困境。

weixin_29191669的博客 281

数据结构-双向链表创建

我们常见的单链表能很好的表示元素间“一对一”的关系,也能根据指针的走向找到某个元素的后继结点,但是对于一些特殊问题,比如需要大量查找到一个元素的前驱结点,单链表总是通过从头向后遍历的方式无疑使运行速度和效率大大降低,为此,我们将引出一个新的链表数据结构,也就是双链表。所以双链表做事更灵活效率更高,单链表显得就有些轴。当然,单链表也有自己的优势,那就是比双链表更加节省空间,因为它只占一个指针域。双链表,也称双向链表,顾名思义,它是具有两个方向的链表,不像单链表形式那么单一,相比单链表多了一个指针域。.....

有朋自远方来,不亦乐乎。 1416

深入解析音频信号处理的核心算法——傅里叶变换、语音增强、回声消除与主动降噪

本文系统介绍了现代音频信号处理的核心技术。首先阐述傅里叶变换作为理论基础的重要性,它能将声音分解为频域成分。随后重点分析三大关键技术:语音增强利用谱减法、维纳滤波和深度学习从噪声中提取人声;回声消除采用自适应滤波器消除通话中的回声;主动降噪通过声波干涉原理抵消环境噪声。文章最后指出,这些技术在实际应用中协同工作,形成完整的音频处理链路,共同提升语音质量和听觉体验。随着算法进步和算力提升,音频处理技术正向着更智能、更高效的方向发展。

程序猿老樊的博客 1327

数据结构+算法连载六 无序-双向链表

单向链表,查找的方向只能是一个方向,而双向链 表可以向前或者向后查找。 单向链表不能自我删除,需要靠辅助节点 ,而双向 链表,则可以自我删除,所以前面我们单链表删除 时节点,总是找到temp,temp是待删除节点的前一 个节点,这次双向链表 temp就直接是待删除的节点。 单向链表的链接如下: 数据结构+算法连载四 单向链表(无序+有序) 数据结构+算法连载五 单向链表的几道练习题 ...

cyberHerman的博客 1441

一种4位sar adc仿真验证

4位sar adc采用下图的电容阵列,电路如下图:所有电容的正端(也称为上极板)与比较器的反相端连接,比较器同相端接Vin,其工作过程进行大致分析见之前的文章《一种4位sar adc工作过程推导(三)》,下面对这个电路进行仿真验证。 两个参考电压VrefPV_{refP}VrefP​和VrefNV_{refN}VrefN​,V+=VinV_{+}=V_{in}V+​=Vin​,假设1116(VrefP−VrefN)+VrefN<Vin<1216(VrefP−VrefN)+VrefN\frac{

大学生视野 1954

[QMT量化交易小白入门]-105、震荡市最适合的策略:ETF多标的动态网格策略,回测年化收益47.81%

本专栏主要是介绍QMT的基础用法,常见函数,写策略的方法,也会分享一些量化交易的思路,大概会写200篇左右。QMT的相关资料较少,在使用过程中不断的摸索,遇到了一些问题,记录下来和大家一起沟通,共同进步。

木头大左的博客 2064

数据结构之双向链表

数据结构之双向链表

容铎的博客 1373

华为OD机考双机位C卷 - 采购订单 (Java & Python& JS & C/C++ & GO )

华为OD机考双机位C卷 - 采购订单 。提供Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。

算法大师! 426

数据结构之自定义双链表

顾名思义:双链表就是在数据域之内还保存了直接前驱和直接后继, 除头尾节点除外, 这种双链表的优点是插入和删除花费的时间为O(1)package link;/* * 双链表 */ public class MyLinkedList<AnyType> implements Iterable<AnyType>{ private int theSize; //除去头尾节点之外的大小(数据的大

LuFei_java的博客 602

AgentScope 2.0 扩展开发完全指南:从中间件到模型适配器的深度实践

本文系统讲解 AgentScope 2.0 框架的五大扩展机制,涵盖中间件系统的洋葱模型与钩子设计、ChatModelBase 基类与多供应商适配器开发、工作空间(本地/Docker/E2B)的抽象接口与生命周期管理、凭据工厂与 MCP 协议集成、以及工具协议与存储后端扩展。文中提供完整的架构图、代码示例与故障排查指南,帮助开发者快速掌握 AgentScope 的插件化扩展体系。

program哲学 296

【Python百日进阶-Web开发-Feffery】Day385 -“一起Dash”训练营Lesson-07_利用fac构建表单(上)

文章目录前言:fac是什么?“人生苦短,我用Python;Web开发,首选Feffery!”↓↓↓ 今日笔记 ↓↓↓一、费老师课堂1.1 什么是表单1.2 页面效果1.3 课堂源码二、课后作业2.1 页面效果2.2 项目源码 前言:fac是什么? feffery-antd-components(简称fac),是国内大佬费弗里(Feffery)老师基于著名的React UI组件库ant design进行二次开发,将ant design中的诸多实用组件及特性引入Dash,帮助开发者使用极低的纯Python代

专注于医院数据分析技术与系统开发的创作与分享。 251

数据结构——动手实战双向链表

本文始发于个人公众号:TechFlow,原创不易,求个关注 在之前介绍SkipList的文章当中,有一些同学反馈说由于对链表缺少认知以及了解,所以直接啃算法有些过于困难。加上之前的文章当中介绍过了栈,所以这次继续线性表这个话题,我们来一起讨论一下链表。 链表是很多数据结构的基础,它的最大特点是支持快速的删除和插入,因此在很多数据频繁变动的场景下使用广泛。而且链表的可拓展性较强,所以它的应用非常广...

TechFlow的博客 385

29、5G PUCCH格式及资源配置详解

本文详细解析了5G通信系统中的物理上行控制信道(PUCCH)的不同格式及其资源配置方案。PUCCH负责传输上行控制信息(UCI),包括混合自动重传请求(HARQ)确认信息、调度请求(SR)和信道状态信息(CSI)等。文章从PUCCH的基本概念出发,深入分析了格式0到格式4的特点、编码调制方式、干扰随机化机制以及适用场景,并探讨了PUCCH资源集的配置方法和上行控制信令在PUSCH上的传输机制。通过对比不同格式的传输能力、干扰随机化方式和频率跳变能力,为读者提供了选择合适PUCCH格式的决策依据。最后,文章总

oil88的博客 252

双向链表详解

🐒🐒🐒🥸🥸🥸🐿️🐿️🐿️🐣🐣🐣🐓🐓🐓以下我写的一些文章,如果在阅读这篇文章过程中有疑惑的可以看一下malloc free等函数的用法free空间等一些问题计算结构体内存大小的方法计算结构体内存大小的方法结构体的用法指针的用法指针的用法,以及野指针问题,和assert用法二级指针。

2401_86956109的博客 1795

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

数据结构——链表

轻松无痛玩转链表

HZzzzzLu的博客 1万+

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

【数据结构】链表

【数据结构】链表

XJ2536877903的博客 1112

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

双向链表

无头结点的双向链表的一般操作。 声明 本文针对的是无头结点的双链表,而下文所出现的头结点所表示的指的是双链表的第一个结点。文中可能出现语句不当的情况,但绝不会影响读者对本文的理解,请以宽容、乐观的心态阅读本文。文中可能会出现一些错误,在此提前向读者致以歉意,并欢迎在评论区留言指正! 说在前面 和线性链表一样,我们无论创建怎样的双向链表都不可能装得下整个世界。所以我们考虑某一元素,用整个世界去包含该...

Chinanjing的博客 422

数据结构之带头双向链表(易学版)

链表的学习我认为是一个先苦后甜的过程,把单链表的原理搞懂之后,再使用双链表就完全是如鱼得水了。学习也是一样,先吃苦,以后才能尝到生活的甜头。最后关于链表的问题,我强烈建议大家刷题巩固,踏实稳重,才能把数据结构这个难关拿下。

cklshidad666的博客 1780

动画:面试如何轻松手写链表?

写在前边 暑假参加的第一个公司的就让我手写一个双向链表,并完成插入数据和删除数据的操作。当时我很蒙蔽,懵逼的不是思路,而是手写,虽然写出来了,但是很多边界条件和代码规范自我感觉不好,所以有了这些细心的总结。那么今天的主题就是徒手写链表,应聘者该如何下手? 我们通常写链表准备应聘的时候,通常背加上理解,但是过了几天又让你写。就会陌生了,虽然有点思路。还是模模糊糊,小鹿也有这个记性的“毛病”,“有毛病...

小鹿动画学编程 2万+

数据结构——带头循环双向链表(List)

为了实现链表的双向结构,我们需要从定义入手。单链表的链表结点定义是一个指向下一个结点的指针,而双向链表则需要两个指针,分别指向上一个和下一个结点。}LTNode;

XLZ_44847的博客 747

设某链表中最常用的操作是在链表的尾部_动画:面试如何轻松手写链表?

写在前边暑假参加的第一个公司的就让我手写一个双向链表,并完成插入数据和删除数据的操作。当时我很蒙蔽,懵逼的不是思路,而是手写,虽然写出来了,但是很多边界条件和代码规范自我感觉不好,所以有了这些细心的总结。那么今天的主题就是徒手写链表,应聘者该如何下手?我们通常写链表准备应聘的时候,通常背加上理解,但是过了几天又让你写。就会陌生了,虽然有点思路。还是模模糊糊,小鹿也有这个记性的“毛病”,“有毛病”就...

weixin_39923572的博客 279

数据结构与算法:线性表之双链表的基本操作

一、循环链表 定义:循环链表是另一种形式的链式存储结构,它的特点是表中最后一个结点的指针指向头结点,整个链表形成一个环。由此,可以从表中任一结点出发均可寻找到表中其他结点。 二、双向链表 定义:双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点 单向链表特点:   1.我们可以轻松的到达下一个节点, 但是回到前一个节点是很难的.   2.只能从头遍历到尾或者从尾遍历到头(一般从头到尾)

林一百二十八的博客 950

C++ STL list模拟实现:从双向链表到迭代器设计的完整解析

在C++编程中,数据结构是构建高效程序的基础,其中链表作为一种经典的线性数据结构,以其动态内存分配和高效的插入删除操作而著称。其核心原理是通过节点间的指针链接实现数据元素的非连续存储,这为频繁的中间插入删除场景提供了O(1)的时间复杂度优势。这种技术价值在需要灵活数据管理的场景中尤为突出,例如实现LRU缓存、管理游戏对象链表或处理事务日志。通过深入实践双向循环链表与哨兵节点的工程实现,开发者能透彻理解迭代器失效、深拷贝控制等C++核心机制。本文聚焦于C++ STL list的模拟实现,详细剖析了其底层数据结

fanjava 343
上一篇: 【链表面试题:腾讯】反转链表
下一篇: 看小朋友做游戏顿时解决了约瑟夫问题
冷环渊
博客等级 码龄7年 1130粉丝 176原创
评论 17
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冷环渊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值