【Java数据结构 -- 实现双链表的接口方法】

news2024/11/17 2:57:06

双链表

  • 1.双链表
  • 2.双链表的创建
  • 3.双链表的头插节点
  • 4.双链表尾插
  • 5.双链表根据索引找节点
  • 6.双链表根据索引插入节点
  • 7.双链表删除值为key的节点
  • 8.删除所有值为key的节点
  • 9.双链表是否包含值为key节点
  • 10.双链表大小
  • 11.清空双链表
  • 12.打印双链表

1.双链表

双链表是一种数据结构,其中每个节点包含一个指向前一个节点的指针和一个指向后一个节点的指针。由于链表没有将元素存储在连续的空间中,元素存储在单独的节点中,然后通过引用将节点连接起来,因此双链表可以任意且快速的插入和删除元素。
在这里插入图片描述

2.双链表的创建

引用接口IList,在把IList接口里面的方法进行重写,实现双链表的功能。把双链表封装成一个类,类中封装一个节点类ListNode,里面的节点类有当前节点的值val、指向前一个节点的ListNode prev和指向后一个节点的变量ListNode next。最后在外部类中定义头节点、尾节点,利用外部类的构造器中就可以对头尾节点的初始化。

public class MyLinkedList implements IList{
    static class ListNode {
        public int val;
        public ListNode next;
        public ListNode prev;

        public ListNode(int val) {
            this.val = val;
        }
    }
    public ListNode head;
    public ListNode last;
}

3.双链表的头插节点

头插node节点,如果链表为空,直接把插入的节点设为头尾节点,不为空把node的下一个节点指向head头节点,再把head的前节点指向node,最后把head指向node。
在这里插入图片描述

    public void addFirst(int data) {
        ListNode node = new ListNode(data);

        if (head == null) {
            head = node;
            last = node;
        }else {
            node.next = head;
            head.prev = node;
            head = node;
        }
    }

4.双链表尾插

尾插node节点,如果链表为空,直接把插入的节点设为头尾节点,不为空把last尾节点的next(即后节点)指向node,再把node的前节点prev指向last,最后把尾节点last指向node。
在这里插入图片描述

    @Override
    public void addLast(int data) {
        ListNode node = new ListNode(data);
        if (head == null) {
            head = node;
            last = node;
        }else {
            last.next = node;
            node.prev = last;
            last = node;
        }
    }

5.双链表根据索引找节点

定义一个count变量来计数,从头节点开始遍历,当计数值为索引值退出循环,返回cur为插入节点的后节点。

    private ListNode findIndex(int index) {
        int count = 0;
        ListNode cur = head;
        while (count != index) {
            count++;
            cur = cur.next;
        }
        return cur;
    }

6.双链表根据索引插入节点

根据索引插入可分三种情况:

  • 当在最前面插入节点时为头插法
  • 在最后一个位置插入则是尾插法
  • 中间插入时遍历链表找到插入节点为node的下标,然后1:把node的后节点指向cur 即node.next = cur;2:把cur前节点的后节点指向node,即cur.prev.next = node;3:把node的前节点指向cur的前节点,即node.prev = cur.prev;4:把cur的前节点指向node,即cur.prev = node。
    在这里插入图片描述
    @Override
    public void addIndex(int index, int data) throws IndexException{
        if (index < 0 || index > size()) {
            throw new IndexException("双向链表插入,index不合法"+index);
        }

        ListNode node = new ListNode(data);
        // 在0位置就是头插法
        if(index == 0) {
            addFirst(data);
            return;
        }

        // 在最后一个位置插入
        if (index == size()) {
            addLast(data);
            return;
        }

        // 中间
        ListNode cur = findIndex(index);
        node.next = cur;
        cur.prev.next = node;
        node.prev = cur.prev;
        cur.prev = node;
    }
}

7.双链表删除值为key的节点

遍历链表,若cur.val为key,删除cur节点

  • 若cur为head头节点时,把head指向head的后节点,当head不为空时,把head的前节点直接置为null,只有一个节点时直接把last指向null。
  • 当cur不等于头节点head时,把cur前节点的后节点指向cur的后节点,即:cur.prev.next = cur.next。若cur的后节点不为空即删除中间节点时:把cur的后节点的前节点指向cur的前节点,即:cur.next.prev = cur.prev,若cur为尾节点时,把last指向last的前节点,即:last = last.prev。
  • 在这里插入图片描述
    @Override
    public void remove(int key) {
        ListNode cur = head;
        while (cur != null) {
            if (cur.val == key) {
                if (cur == head) {
                    head = head.next;
                    if (head != null) {
                        head.prev = null;
                    }else {
                        //只有一个节点 且是需要删除的节点
                        last = null;
                    }
                }else {
                    cur.prev.next = cur.next;
                    //删除中间节点
                    if (cur.next != null) {
                        //cur.prev.next = cur.next;
                        cur.next.prev = cur.prev;
                    }else {
                        // 删除尾巴节点
                        //cur.next.prev = cur.next;
                        last = last.prev;
                    }
                }
                return;
            }
            cur = cur.next;
        }
    }

8.删除所有值为key的节点

即上面删除完第一个key的节点之后不跳出循环,接着删除。

    @Override
    public void removeAllKey(int key) {
        ListNode cur = head;
        while (cur != null) {
            if (cur.val == key) {
                if (cur == head) {
                    head = head.next;
                    if (head != null) {
                        head.prev = null;
                    }else {
                        //只有一个节点 且是需要删除的节点
                        last = null;
                    }
                }else {
                    cur.prev.next = cur.next;
                    //删除中间节点
                    if (cur.next != null) {
                        //cur.prev.next = cur.next;
                        cur.next.prev = cur.prev;
                    }else {
                        // 删除尾巴节点
                        //cur.next.prev = cur.next;
                        last = last.prev;
                    }
                }
            }
            cur = cur.next;
        }
    }

9.双链表是否包含值为key节点

    @Override
    public boolean contains(int key) {
        ListNode cur = head;
        while (cur != null) {
            if (cur.val == key) {
                return true;
            }
            cur = cur.next;
        }
        return false;
    }

10.双链表大小

    @Override
    public int size() {
        int count = 0;
        ListNode cur = head;
        while (cur != null) {
            count++;
            cur = cur.next;
        }
        return count;
    }

11.清空双链表

    @Override
    public void clear() {
        ListNode cur = head;
        while (cur != null) {
            ListNode curNext = cur.next;
            cur.next = null;
            cur.prev = null;
            cur = curNext;
        }
        this.head = null;
        this.last = null;
    }

12.打印双链表

    @Override
    public void display() {
        ListNode cur = head;
        while (cur != null) {
            System.out.print(cur.val + " ");
            cur = cur.next;
        }
        System.out.println();
    }

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

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

相关文章

【MATLAB】 SSA奇异谱分析信号分解算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~ 1 基本定义 SSA奇异谱分析&#xff08;Singular Spectrum Analysis&#xff09;是一种处理非线性时间序列数据的方法&#xff0c;可以对时间序列进行分析和预测。 它基于构造在时间序列上的特定矩阵的奇异值分解&#…

部署YUM仓库及NFS共享存储

引言&#xff1a; 学习YUM 软件仓库&#xff0c;可以完成安装、卸载、自动升级 rpm 软件包等任务&#xff0c;能够自动 查找并解决 rpm 包之间的依赖关系&#xff0c;而无须管理员逐个、手工地去安装每个 rpm 包&#xff0c;使管理员在维护大量 Linux 服务器时更加轻松自如。特…

20240116-【UNITY 学习】增加滑动功能

替换脚本PlayerMovement_02.cs using System.Collections; using System.Collections.Generic; using UnityEngine;public class PlayerMovement_03 : MonoBehaviour {private float moveSpeed; // 玩家移动速度public float walkSpeed 7; // 行走速度public float sprintSpee…

竞赛保研 基于深度学习的水果识别 设计 开题 技术

1 前言 Hi&#xff0c;大家好&#xff0c;这里是丹成学长&#xff0c;今天做一个 基于深度学习的水果识别demo 这是一个较为新颖的竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f9ff; 更多资料, 项目分享&#xff1a; https://gitee.com/dancheng-senior/pos…

图像处理:孤立点的检测

图像处理-孤立点的检测 孤立点的检测在图像处理中通常涉及到检测图像中的突变或者边缘&#xff0c;而使用二阶导数是一种常见的方法。一阶导数可以帮助找到图像中的边缘&#xff0c;而二阶导数则有助于检测边缘上的峰值&#xff0c;这些峰值可能对应于孤立点或者特殊的图像结构…

2024美赛数学建模思路 - 案例:FPTree-频繁模式树算法

文章目录 算法介绍FP树表示法构建FP树实现代码 建模资料 ## 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 算法介绍 FP-Tree算法全称是FrequentPattern Tree算法&#xff0c;就是频繁模式树算法&#xff0c…

帆软笔记-决策表报对象使用(两表格联动)

效果描述如下&#xff1a; 数据库中有个聚合商表&#xff0c;和一个储能表&#xff0c;储能属于聚合商&#xff0c;桩表中有个字段是所属聚合商。 要求帆软有2个表格&#xff0c;点击某个聚合商&#xff0c;展示指定的储能数据。 操作&#xff1a; 帆软选中表格单元&#xf…

Windows Server 2019配置DNS服务器

正文共&#xff1a;1234 字 31 图&#xff0c;预估阅读时间&#xff1a;1 分钟 我们在给Windows Server添加角色和功能时&#xff0c;会发现有一项“远程桌面服务安装”&#xff0c;它的介绍为“为虚拟桌面基础结构&#xff08;Virtual Desktop Infrastructure&#xff0c;VDI&…

PyTorch Tutorial 2.0

这里是对于PyTorch Tutorial-CSDN博客的补充&#xff0c;但是与其相关的NLP内容无关&#xff0c;只是一些基础的PyTorch用法的记录&#xff0c;主要目的是能够自己生成一些模拟的数据集。先介绍随机数的目的是因为based on随机数方法。 当然在看随机数的方法的时候&#xff0c…

Python 最新版本 3.12.1 环境配置(windows)

文章目录 python 3.12.1环境安装3.12.1 网盘下载3.12.1 官网下载 python 安装完成测试第一个 python 程序Hello Python python 3.12.1环境安装 3.12.1 网盘下载 python 3.12.1 百度网盘地址&#xff1a;https://pan.baidu.com/s/1SAcH_uH0T3DiERn6AZeQlg?pwd4242 提取码&a…

java-Lambda 语法总结

文章目录 Lambda 语法概览Lambda 表达式语法1.Lambda 表达式与函数接口2.Lambda 遇上 this final Lambda 语法概览 String(] names {”Justi n ”,”caterpillar”,”Bush " }; Arrays . sort (names, new Compara tor<String> () { publ int compare (String na…

伪装目标检测模型论文阅读之:Zoom in and out

论文链接&#xff1a;https://arxiv.org/abs/2203.02688 代码;https://github.com/lartpang/zoomnet 1.摘要 最近提出的遮挡对象检测&#xff08;COD&#xff09;试图分割视觉上与其周围环境融合的对象&#xff0c;这在现实场景中是非常复杂和困难的。除了与它们的背景具有高…

布隆过滤器四种实现(Java,Guava,hutool,Redisson)

1.背景 为预防大量黑客故意发起非法的时间查询请求&#xff0c;造成缓存击穿&#xff0c;建议采用布隆过滤器的方法解决。布隆过滤器通过一个很长的二进制向量和一系列随机映射函数&#xff08;哈希函数&#xff09;来记录与识别某个数据是否在一个集合中。如果数据不在集合中…

两个方法实现echarts散点图的高光圆点

一、效果图&#xff1a; 二、代码 方法一&#xff1a;通过series的itemStyle进行设置&#xff0c;type为scatter 在 ECharts 中&#xff0c;要在二维散点图上实现看似 3D 的高光圆点效果&#xff0c;可以通过自定义散点图的 itemStyle 属性来实现。虽然无法直接创建真正的 3D…

Flume 之自定义 Source

1、简介 Flume 自带 Source 有 Avro、Thrift、Netcat、Taildir、Kafka、Http等&#xff0c;有些场合比如我们指定访问接口获取数据当做 Flume 的 Source&#xff0c;像这种定制化的 Source 需要我们自己实现&#xff0c;下面我将介绍如何自定义实现 Source。 2、自定义实现 Fl…

Linux中放大字体

环境&#xff1a;VMware17Pro&#xff0c;Ubuntu22.04 在显示设置外观中只看到图标放大的调整&#xff0c;没看到字体大小设置 不按照常规设置&#xff0c;点开下面的辅助功能->大号文本&#xff08;没有设置具体字号的选项&#xff0c;但是可以放大&#xff09; 效果图如下…

五、带登录窗体的demo

做了一个简单的带登录窗体的demo&#xff0c;有用户名和密码不能为空的验证&#xff0c;原理是在main.cpp的主函数入口处&#xff1a; 1、将默认的MainWindow主窗体注释。 2、新建一个formlogin登录窗体&#xff0c;在主函数中先运行登录窗体。 3、在登录窗体中引用MainWind…

Monorepo-uniapp 构建分享

Monorepo uniapp 构建灵感&#xff1a;刚好要做一个项目&#xff0c;于是想到升级一下之前自己写的一个vue3tspiniauno的模版框架&#xff0c;其实那个框架也不错&#xff1b;只是感觉还差点东西&#xff0c;我已经用那个小框架写了两三个项目&#xff1b;轻巧实用。为什么选…

线性代数——行列式按行(列)展开

目录 一、余子式&#xff1a;将行列式某元素所在行和列的元素全去掉 剩余部分所构成的行列式&#xff0c;称为该元素的余子式 二、代数余子式 三、行列式等于它的任一行&#xff08;列&#xff09;的各元素与对应代数余子式乘积之和 四、行列式某行元素&#xff08;列&…

transbigdata 笔记: 官方文档示例3:车辆轨迹数据处理

1 读取数据 轨迹数据质量分析 这一部分和 transbigdata笔记&#xff1a;data_summary 轨迹数据质量/采样间隔分析-CSDN博客 的举例是一样的 import pandas as pd import geopandas as gpd import transbigdata as tbddata pd.read_csv(Downloads/TaxiData-Sample.csv, names…