数据结构 - 双向链表

news2024/11/15 13:41:11

文章目录

目录

文章目录

前言

一、什么是双向链表?

双向链表有什么优势?

二、双向链表的设计和实现

1.设计思想

尾增 : 在链表的末尾添加新的元素

 头插 : 在链表头部插入节点

 删除 : 根据val的值删除节点

 查找 : 根据索引的值查找并返回节点

总结



前言

大家好,今天给大家讲解一下双向链表的设计和实现,和单向链表不同的是,双向链表中加入了指向前一个节点的指针。


一、什么是双向链表?

如上图所示,双向链表中包含了两个指针,一个指向前驱结点,一个指向后继节点,其中头结点没有前驱节点,尾结点没有后继节点

前驱 : 前驱指的是当前节点的前一个节点,即在链表中位于当前节点之前的节点。它可以通过前向指针(previous pointer)来访问。

后继 : 后继指的是当前节点的后一个节点,即在链表中位于当前节点之后的节点。它可以通过后向指针(next pointer)来访问。

双向链表有什么优势?

相对于单链表,双向链表具有以下优势:

  1. 可以从任意一个节点开始进行正向或反向遍历。由于每个节点都有指向前一个节点和后一个节点的指针,因此可以方便地在链表中进行前向和后向的遍历操作。

  2. 在插入和删除节点时,不需要遍历整个链表来找到前一个节点。在单链表中,如果要在某个节点之后插入或删除节点,需要先找到该节点的前一个节点,而双向链表可以直接通过指针找到前一个节点,从而提高了插入和删除操作的效率。

  3. 双向链表可以更方便地实现反向查找。在单链表中,如果要查找某个节点的前一个节点,需要从头节点开始遍历整个链表,而双向链表可以通过后向指针直接找到前一个节点,从而实现了反向查找。

总之,双向链表相对于单链表在遍历、插入和删除操作上具有更高的效率和灵活性。然而,双向链表的缺点是需要更多的内存空间来存储额外的指针。

二、双向链表的设计和实现

1.设计思想

前言 : 为了简单起见,我们在类中只定义最基本的属性

节点类: 不管是双向链表还是单向链表,都是有节点所构成,所以说节点类是必不可少的(值得一提的是,节点类不一定要定义成外部类,这么一想,好像定义成内部类更加合适,毕竟节点是链表的一部分,大家如果自己实现的话可以使用内部类的方式,由于我写博客准备的就是外部类的方式,在此就不做修改)

链表类: 类中应该需要包含什么信息? 聪明的读者肯定已经想到了吧,节点啊! 你们都是聪明人啊,除了节点之外我们还需要包含一个成员变量Head(链表的头结点),一个构造方法(链表写出来是给别人用的),还有其他的成员方法(自己设计)。

下面给出框架代码

public class List {
    private Node head;// 头结点

    public List() {

    }

// 节点类
class Node {
    int val;
    Node prev;
    Node next;

    public Node() {
    }

    public Node(int val) {
        this.val = val;
    }

    @Override
    public String toString() {
        return "Node{" +
                "no=" + val +
                ", prev=" + prev +
                ", next=" + next +
                '}';
    }
}

2.代码实现

前言 : 为了简单起见,我们下面只实现基本方法并且只重点针对性的解析我认为对初学者有难度的代码部分

和前面的部分代码相同,有些很简单的方法直接给出

/*
* 链表中元素的个数
* */
public int getSize(){
    Node cur = head;
    
    int count = 0;
    
    while(cur != null){
        cur = cur.next;
        count++;
    }
    return count;
}

/*
* 判断链表是否为空
* */
public Boolean IsEmpty() {
    return head == null;
}

尾增 : 在链表的末尾添加新的元素

public void addNode(int val) {
    Node node = new Node(val);
    if (IsEmpty()) {
        // 链表为空,该节点为新头
        head = node;
    }

    Node cur = head;

    while (cur.next != null) {
        cur = cur.next;
    }

    // 此时的cur就表示最后一个节点
    cur.next = node;
    node.prev = cur;
}

 头插 : 在链表头部插入节点

不知道初学者有没有感觉到什么难度,个人感觉这些代码都是很基础的,所以没有进行解析

如果有问题的可以在评论区提出,我再进行修改

public void addFirst(int val){
    Node newNode = new Node(val);
    if(IsEmpty()){
        head = newNode;
    }
    newNode.next = head;
    head.prev = newNode;
    head = newNode;
}

 删除 : 根据val的值删除节点

这个和单链表比起来就简单多了,在单链表中需要找到值为val的前一个节点,还需要判断头结点为val的情况,大家搞清楚单链表中的方法,双向链表中的这个就是弟弟!

// 根据节点的no值删除节点
public void DeleteNode(int no) {
    int count = 0;// 记录被删除节点的个数
    
    if(IsEmpty()){
        System.out.println("链表为空");
        return;
    }
    Node cur = head;// 将head的值赋给变量cur,使其代替head进行循环遍历
    while(true){
        if(cur == null){
            System.out.println("共删除了"+count+"个节点");
            // 链表中已经没有值为no的节点,跳出循环
            break;
        }

        if(cur.val == no){
            Node prev = cur.prev;// 记录将要被删除的节点的上一个节点
            cur = cur.next;// 用下一个节点覆盖当前节点
            cur.prev = prev;
            count++;
            continue;
        }
        cur = cur.next;
    }

 查找 : 根据索引的值查找并返回节点

// 根据索引查找节点
public Node findNode(int index) throws IndexException {
    // 索引是否合法,一看到和索引相关的问题就应该要想一下是否需要判断索引的合法性,此处需要判断
    if(index < 0 || index >= getSize()){
        // 自定义异常来表示索引越界这种不合法的行为
        throw new IndexException("索引越界");
    }
    
    Node cur = head;
    while(index > 0){
        index--;
        cur = cur.next;
    }
    
    return cur;
}

 写到这里不得不感慨一下JAVA中的深情哥-Exception(异常)-上_喜欢吃animal milk的博客-CSDN博客的下篇到现在还没写

到这里就结束了,方法在精不在多,自行领悟吧!


总结

这篇博客大家应重点关注链表的设计,代码这个东西面试考的更多的是单链表,大家刷题更多的也是单链表,双向链表相对于就没有那么重要了。

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

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

相关文章

Window安装虚拟机+给虚拟机安装Linux

一、虚拟机下载 这里使用Virtualbox虚拟机。可以直接从官网下载&#xff1a;Downloads – Oracle VM VirtualBox 点击进行下载&#xff0c;选择window版本的。直接双击&#xff0c;一直下一步 进行安装 PS&#xff1a;安装需要开启CPU虚拟化&#xff0c;一般电脑都已经开启了…

【大麦小米学量化】使用天勤TqSdk实现期货量化交易(入门)

文章目录 酱香拿铁的故事一、TqSdk 是什么&#xff1f;二、准备工作1. 安装tqsdk库&#xff08;Python环境提前准备好&#xff09;2. 注册快期账户3. 支持的期货公司&#xff08;更新以官方公布为准&#xff09; 三、初试牛刀1. 示例代码&#xff1a;2. 运行后提示如下&#xf…

VIT中的einops包详解

‘’‘einops有三个常用方法&#xff1a;rearrange,repeat,reduce’‘’ rearrange的操作相当于转置 rearrange(image,‘h w c -> w h c’) 高和宽转置 path ../data/cat_and_mouse.jpg image cv2.imread(path) h,w,c image.shape # shape第一个值是h,第二个是w image…

Vue框架--Vue列表渲染(1)

1.列表的基本遍历 Vue提供了v-for用于遍历数据内容,我们在这里重点说两种数据的遍历:数组的遍历和对象的遍历。遍历数组对象如下所示: 遍历对象案例:

vue3项目部署报错 Faled to esolve entry for pacdlage “hntlify/sthared“

版本 vue 3.2.47 vue-i18n 9.2.2 本地运行没有问题&#xff0c;jenkins上部署报错找不到"hntlify/sthared"包 排查问题&#xff1a; 查看vue-i18n官网&#xff0c;发现有引用到这个包 “hntlify/sthared” vue-i18n最新版本是9.3.0&#xff0c;未锁定版本&#xf…

Excel 将数字添加百分号

目的&#xff1a;将56.33变成56.33% 打一个“100”&#xff0c;然后ctrlc复制 全选要操作的数据&#xff0c;右键&#xff0c;选择“选择性张贴” 选择“除” 再选择“百分比” 可以调整位数 软件工程小施同学 20230907

【0907 C高级day2】Shell脚本

一、作业&#xff1a;写一个shell脚本&#xff0c;将以下内容放到脚本中 在家目录下创建目录文件&#xff0c;dir在dir下创建dir1和dir2把当前目录下的所有文件拷贝到dir1中&#xff0c;把当前目录下的所有脚本文件拷贝到dir2中把dir2打包并压缩为dir2.tar.xz再把dir2.tar.xz移…

Mac上的视频管理神器:MetaVideo for Mac让你的视频搜索和整理更轻松

视频时代已经来临&#xff0c;我们每天都会接触到各种各样的视频资源。但是&#xff0c;如何管理和编辑这些视频文件&#xff0c;让它们更加易于查找和使用呢&#xff1f;MetaVideo for Mac可以帮助你解决这个问题。 MetaVideo for Mac是一款专门为Mac用户设计的视频管理软件&…

2023京东医疗保健器械行业数据分析(京东数据分析平台)

随着人们对自身健康的重视程度不断加深&#xff0c;当前市场中各类对疾病具有诊断、预防、监护、治疗或者缓解的医疗保健仪器越来越受到消费者的关注。 根据鲸参谋电商数据分析平台的相关数据显示&#xff0c;今年7月份&#xff0c;京东平台医疗保健仪器的销量为950万&#xf…

Java“牵手”1688商品详情数据,1688商品详情API接口,1688API接口申请指南

1688平台商品详情接口是开放平台提供的一种API接口&#xff0c;通过调用API接口&#xff0c;开发者可以获取1688商品的标题、价格、库存、月销量、总销量、库存、详情描述、图片等详细信息 。 获取商品详情接口API是一种用于获取电商平台上商品详情数据的接口&#xff0c;通过…

【广州华锐互动】VR景区云游:打造沉浸式网上虚拟旅游体验

VR景区云游体验是一种全新的旅游体验方式&#xff0c;通过虚拟现实技术&#xff0c;让游客在家中就能身临其境地游览各大景区。这种展示方式不仅节省了游客的时间和金钱&#xff0c;还能让他们在未出发前就对景区有更深入的了解。 通过虚拟现实技术&#xff0c;用户可以在景区内…

java String拼接json的方式

首先要晓得json显示的格式&#xff0c;就晓得下面为啥要这样拼接了 1.通过转义符号拼接 String content2 "{\"order\":{\"terminalNumber\":\"""""\"" ",\"listFlag\":"&q…

c高级day2作业

写一个1.sh脚本&#xff0c;将以下内容放到脚本中&#xff1a; 在家目录下创建目录文件&#xff0c;dir 在dir下创建dir1和dir2 把当前目录下的所有文件拷贝到dir1中&#xff0c; 把当前目录下的所有脚本文件拷贝到dir2中 把dir2打包并压缩为dir2.tar.xz 再把dir2.tar.xz…

自动化运维—ansible

一、 Ansible 介绍 Ansible 是一种 IT 自动化工具。它可以配置管理&#xff0c;部署软件以及协调更高级的 IT 任务&#xff0c; 例如持续部署&#xff0c;滚动更新。 Ansible 适用于管理企业 IT 基础设施&#xff0c;从 几十台到上百台的服务器环境。Ansible 也是一种简单的自…

既是管理又是执行者,如何清晰地进行工作总结呢?

摘要&#xff1a;作为管理者和执行者&#xff0c;清晰地进行工作总结对于提高效率和推动团队发展至关重要。本文将探讨一些技巧和方法&#xff0c;帮助管理者清晰地进行工作总结。 正文&#xff1a; 工作总结对于管理者来说是一项关键任务&#xff0c;它可以帮助回顾工作进展…

selenium自动化测试过程中接口的调用信息

在上一篇中我也给自己提出一个需求&#xff1a;如果记录在测试过程中接口的调用情况&#xff1f;提出这个需求&#xff0c;我觉得是有意义的。你在测试过程中肯定会遇到一些莫名其妙的问题&#xff0c;比如&#xff1a;web某个页面一直在刷进度条&#xff0c;导致你定位元素失败…

kubernetes 之 minikube折腾记

参考官网教程&#xff0c;链接&#xff1a; https://minikube.sigs.k8s.io/docs/start/ curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 sudo install minikube-linux-amd64 /usr/local/bin/minikube安装完启动minikube&#xff1a;…

超高真空度精密控制解决方案设计中百度“文心一言”的具体应用

摘要&#xff1a;本文采用国产版本ChatGPT百度“文心一言”作为一种辅助工具&#xff0c;针对超高真空度精密控制装置的开发进行了初期的技术路线设计&#xff0c;对话调研的重点是了解可调节式微流量进气阀门和可用于连接非线性输出信号型真空计的PID控制器。总体而言&#xf…

【容器vs虚拟机】

容器vs虚拟机 为什么用虚拟机什么是容器容器vs虚拟机 Docker被称为是轻量级的虚拟化。 首先&#xff0c;一般开发所需要的都是Linux环境&#xff0c;但我们大多数人的电脑都是Windows系统。所以要安装虚拟机&#xff0c;目的是为了在我们当前所使用的Windows上面安装上Linux环境…