Java 数据结构之双向链表

2023-11-14

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lovoo/article/details/51771321

一、概述:

1、什么时双向链表: 
链表中的每个节点即指向前面一个节点,也指向后面一个节点,就像丢手绢游戏一样,每个人都手拉手 
这里写图片描述

2、从头部插入 
要对链表进行判断,如果为空则设置尾节点为新添加的节点,如果不为空,还要设置头节点的一个前节点为新节点 
这里写图片描述

3、从尾部进行插入 
如果链表为空,则直接设置头节点为新添加的节点,否则设置尾节点的后一个节点为新添加的节点。同时设置新添加的节点的前一个节点为尾节点 
这里写图片描述

4、从头部删除 
判断节点是否有下个节点,如果没有则设置节点为null,并且删除下个节点指向前节点的指针

5、删除尾部节点 
如果头节点没有其它节点,把尾节点设置为Null。否则设置尾节点前一个节点的next为Null。设置尾节点为前一个节点 
这里写图片描述

6、删除方法 
此时不需要记录last的Node 
删除时使用current.previous.next= current.next;

二、实现:

 

package com.struct.linklist;


/**
 * @描述         双向链表
 * @项目名称      Java_DataStruct
 * @包名         com.struct.linklist
 * @类名         LinkList
 * @author      chenlin
 * @date        2010年6月26日 上午8:00:28
 * @version     1.0 
 */

public class DoubleLinkList {

    //头
    private Node first;
    //尾
    private Node last;

    public DoubleLinkList(){
        first = null;
        last = null;
    }

    /**
     * 插入数据
     * @param value
     */
    public void insertFirst(long value){
        Node newNode = new Node(value);
        if (first == null) {
            last = newNode;
        }else {
            first.previous = newNode;
            //把first节点往下移动
            newNode.next = first;
        }
        //把插入的节点作为新的节点
        first = newNode; 
    }

    /**
     * 插入数据
     * @param value
     */
    public void insertLast(long value){
        Node newNode = new Node(value);
        if (first == null) {
            first = newNode;
        }else {
            last.next = newNode;
            //first.previous = newNode;
            newNode.previous = last;
        }
        //把最后个节点设置为最新的节点
        last = newNode;
    }

    public boolean isEmpty(){
        return first == null;
    }

    /**
     * 删除头节点时要去除两个指针,一个指向下个的next ,一个是next的previous指向前面的
     * 
     * @param value
     * @return
     */
    public Node deleteFirst(){
        if (first == null) {
            throw new RuntimeException("链表数据不存在");
        }
        Node temp = first;
        if (first.next == null) {
            last = null;
        }else {
            first.next.previous = null;
        }
        first = temp.next;
        return temp;
    }

    /**
     * 删除头节点时要去除两个指针,一个指向下个的next ,一个是next的previous指向前面的
     * 
     * @param value
     * @return
     */
    public Node deleteLast(){
        if (first == null) {
            throw new RuntimeException("链表数据不存在");
        }

        Node temp = last;
        if (first.next == null) {
            last = null;
            //把第一个删除
            first = null;
        }else {
            last.previous.next = null;
        }
        last = temp.previous;
        return temp;
    }

    /**
     * 删除
     * @param key
     * @return
     */
    public Node deleteByKey(long key){
        Node current = first;
        while(current.data != key){
            if (current.next == null) {
                System.out.println("没找到节点");
                return null;
            }
            current = current.next;
        }
        if (current == first) {
            //return deleteFirst();
            //指向下个就表示删除第一个
            first = first.next;
        }else {
            current.previous.next = current.next;
        }
        return current;
    }

    /**
     * 显示所有的数据
     */
    public void display(){
        if (first == null) {
            //throw new RuntimeException("链表数据不存在");
            return;
        }
        Node current = first;
        while(current != null){
            current.display();
            current = current.next;
        }
        System.out.println("---------------");
    }

    /**
     * 查找节点1
     * @param value
     * @return
     */
    public Node findByValue(long value){
        Node current = first;
        while(current != null){
            if (current.data != value) {
                current = current.next;
            }else {
                break;
            }
        }
        if (current == null) {
            System.out.println("没找到");
            return null;
        }
        return current;
    }

    /**
     * 查找节点2
     * 
     * @param key
     * @return
     */
    public Node findByKey(long key) {
        Node current = first;
        while (current.data != key) {
            if (current.next == null) {
                System.out.println("没找到");
                return null;
            }
            current = current.next;
        }
        return current;
    }

    /**
     * 根据索引查找对应的值
     * @param position
     * @return
     */
    public Node findByPosition(int position){
        Node current = first;
        //为什么是position - 1,因为要使用遍历,让current指向下一个, 所以position - 1的下个node就是要找的值
        for (int i = 0; i < position - 1 ; i++) {
            current  = current.next;
        }
        return current;
    }


    public static void main(String[] args) {
        DoubleLinkList linkList = new DoubleLinkList();
        linkList.insertFirst(21);
        linkList.insertFirst(22);
        linkList.insertFirst(23);
        linkList.insertLast(24);
        linkList.insertLast(25);
        linkList.insertLast(26);
        linkList.insertLast(27);

        linkList.display();

        System.out.println("---查找-------------------------------------");

        linkList.findByKey(25).display();

        System.out.println("--删除first-------------------------------------");

        //linkList.deleteFirst().display();
        ///linkList.deleteFirst().display();
        //linkList.deleteFirst().display();
        //linkList.deleteFirst().display();

        System.out.println("-删除指定值---------------------------------------");
        linkList.deleteByKey(27).display();
        linkList.deleteByKey(21).display();

        System.out.println("----------------------------------------");
        linkList.display();


    }
}

 

 

https://blog.csdn.net/lovoo/article/details/51771321

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 数据结构之双向链表 的相关文章

  • SharePoint:如何从列表模板创建新列表?

    我已经根据问题列表创建了一个列表模板 并将其保存在列表模板库中 现在如何基于此模板创建新列表 string internalName MyListTemplateName SPListTemplate t null foreach SPLi
  • python - 如何删除每行中的重复列表(pandas)?

    我的每一行中都包含一个列表 我想通过保留分数中的最高值来删除重复元素 这是我的数据框 df1 中的数据 pair score 0 A A 1 0000 1 A F 0 9990 2 A G 0 9985 3 A G 0 9975 4 A H
  • 当元组列表中相同项目的值是字符串时,对它们的值求和

    如果我有这样的元组列表 my list books 5 books 10 ink 20 paper 15 paper 20 paper 15 我怎样才能把列表变成这样 books 15 ink 20 paper 50 即添加同一项目的费用
  • 将二进制数转换为包含每个二进制数的数组

    我试图将二进制值转换为每个 1 0 的列表 但我得到默认的二进制值而不是列表 我有一个字符串 我将每个字符转换为二进制 它给了我一个列表 其中每个字符都有一个字符串 现在我试图将每个字符串拆分为值为 0 1 的整数 但我什么也得不到 if
  • 如何使用 bash 粘贴来自单独文件的列?

    我想用分隔符 合并不同的列表 第一个列表有 2 个单词 cat first one who 第二个列表有 10000 个单词 cat second languages more simple advanced home expert tes
  • 检查列表是否已排序的 Pythonic 方法

    有没有一种Python式的方法来检查列表是否已经排序ASC or DESC listtimestamps 1 2 3 5 6 7 就像是isttimestamps isSorted 返回True or False 我想输入一些消息的时间戳列
  • 计算列表中的子列表

    L 2 4 5 6 2 1 6 6 3 2 4 5 3 4 5 我想知道任意子序列出现了多少次 s 2 4 5 例如会返回2次 I tried L count s 但它不起作用 因为我认为它期望寻找类似的东西 random numbers
  • 如何将列表 插入数据库

    我是 Java 新手 我已经创建了产品类型的通用列表 如何将其添加到数据库中 该列表包含Products的对象 数据库中的列是Products类的字段 即使我通过 listvariable get 0 等分隔列表 我也会得到对象 而不是该对
  • Haskell:处理死锁的自引用列表

    GHC 允许永久阻止以下内容是否有任何有用的理由 list 1 tail list 看起来列表迭代器 生成器有点复杂 我们应该能够做一些更有用的事情 Return error Infinitely blocking list Return
  • Python 递归搜索带有嵌套键的字典

    我最近必须使用嵌套的字典 列表组合来解决实际数据系统中的问题 我为此工作了很长一段时间并提出了解决方案 但我非常不满意 我不得不求助于使用globals 和一个命名的临时全局参数 我不喜欢使用全局变量 这只是要求注入漏洞 我觉得必须有一种更
  • 生成字符串及其子字符串列表的排列的算法

    我已经忘记这个算法有一段时间了 假设我得到了字符串 cccaatt 我试图生成重复字母的每个子串的所有可能变体 EG cccaatt 作为输入将返回 猫 卡特 猫 卡特 ccat 卡特 卡特彼勒 卡特彼勒 cccat cccat cccaa
  • 向 python 元组添加条目

    我有一个代表 x y 点的元组列表 我还有每个点的值列表 如何将它们组合成列表列表 即每个点 x y val 一个条目 或元组列表 Thanks 您无法向元组添加条目 因为元组是不可变的 但您可以创建一个新的列表列表 new x y val
  • C#动态创建Type数组

    在 C 中 我需要能够在运行时基于以字符串形式传递给函数的逗号分隔数据类型列表创建 Type 对象数组 基本上 这就是我想要实现的目标 create array of types Type paramTypes typeof uint ty
  • 在 python 中高效、快速地迭代元组列表中超过 3600 万个项目

    首先 在任何人将其标记为重复之前 请阅读以下内容 我不确定迭代的延迟是否是由于尺寸巨大或我的逻辑造成的 我有一个必须迭代的用例3600 万件商品在元组列表中 我的主要要求是速度和效率 样本清单 how are you I am fine h
  • 对自身内部列表的递归引用[重复]

    这个问题在这里已经有答案了 所以我在 python 中遇到了一些非常奇怪的东西 我尝试添加对列表本身的引用 该代码可能有助于比我能表达的更好地展示我所说的内容 我正在使用 IDLE 编辑器 交互模式 gt gt gt l 1 2 3 gt
  • 如何向列表添加值>

    我需要将派生类的元素添加到抽象类的共享指针列表中 我一直在尝试这个 我知道我正在尝试在下面的示例中创建抽象类的实例 但我不知道如何使其工作 简化的类如下所示 using namespace std class Abstract public
  • 在 R 中垂直绘制表 kable::extra 和 kable 的列表?

    我需要绘制表格列表一个在另一个之下 显示垂直 有任何想法吗 问题从这里开始 https stackoverflow com questions 73867229 plot a list of tables in a single table
  • Python列表内存存储[重复]

    这个问题在这里已经有答案了 据我了解 Python 列表本质上是 C 数组 它们分配特定的顺序内存块 但是 这些内存块实际上存储列表中的数据还是它们只是指向内存中存储实际数据的另一个位置 它可能取决于列表中存储的对象的大小吗 因为您可以轻松
  • 了解 Scala 中的中缀方法调用和缺点运算符(::)

    我对 Scala 编程语言相当陌生 当我遵循以下网站的讲义时 我正在尝试一些萦绕在我脑海中的东西 here http horstmann com sjsu cs152 04 closures1 html 我想我无法真正理解 cons 运算符
  • 按属性对对象列表进行排序 C#

    我有这门课 public class Leg public int Day get set public int Hour get set public int Min get set 我有一个获取腿列表的函数 称为 GetLegs Lis

随机推荐

  • 跨域问题的原理分析

    一 什么是跨域 当页面来源url 的协议 域名 端口 跟页面发出请求获取后端数据的url 的协议 域名 端口 只有要一个不同时 即为跨域 举个例子 我当前先请求blog csdn net nav lang到csdn服务器获取到一个csdn的
  • Caused by: org.springframework.context.ApplicationContextException: Unable to start ServletWebServer

    错误原因 SpringApplication run 中的类名书写错误 应该是写成springboot启动类的类名而不是其他的 如下所示 我启动类的类名为Main 那么在run方法中应该为Main class而不是其它 SpringBoot
  • RxPermissions简单使用

    RxPermissions简单使用 描述 随着社会的发展人们也开始重视对隐私的保护 谷歌也在Android6 0 sdk 23 增加了动态权限申请来保护广大用户的隐私 使我们开发者实现起来会很繁琐 代码量也会增多 但是对于程序员来说永远都是
  • JWT 身份认证优缺点分析以及常见问题解决方案

    JWT 身份认证优缺点分析以及常见问题解决方案 之前分享了一个使用 Spring Security 实现 JWT 身份认证的 Demo 文章地址 适合初学者入门 Spring Security With JWT 的 Demo Demo 非常
  • javascript基础第二天笔记

    JavaScript 基础 第2天 理解什么是流程控制 知道条件控制的种类并掌握其对应的语法规则 具备利用循环编写简易ATM取款机程序能力 运算符 语句 综合案例 运算符 算术运算符 数字是用来计算的 比如 乘法 除法 加法 减法 等等 所
  • Neo4j使用系列4

    Part4 1 Cypher基础1 类似于关系数据库中使用的SQL 是Neo4j使用的查询语言 1 特点 是一种声明式图形查询语言 富有表现力和高效的查询 更新和管理 设计简单 但功能强大 可以轻松表达高度复杂的数据库查询 Cypher的结
  • MySQL和Oracle时间取整

    按每15分钟时间取整 mysql SELECT now interval TIME TO SEC now mod 900 second from dual 其中now 可以替换为 你自己的 字段 oracle select sysdate
  • 第三方库(wordcloud为例)调用出现种种问题

    刚刚学习了python 想做点小东西练练手 python有很多好玩的东西 turtle库 wordcloud等等一系列我觉得都可以用来练练手并且真的是挺好玩 本来寻思也就十多行代码 肯定一会就能调试完 没想到 真的是我太天真 本来就不怎么会
  • 笔记本拓展外接显示器时 鼠标移动不到主显示器外的另一块屏上

    原因 显示面板 两个显示器图形表示 如下图带有标号的方块 摆放顺序不正确 把代表左边显示器的图标拖动到左侧即可
  • 从零到熟练编写LaTex数学公式,这两篇就够了

    第一篇 LaTex公式编辑方法 快速手敲一遍 熟悉常用操作 第二篇 CSDN官方参考文档 有不清楚的 随手查阅 在线公式编辑 实在打不出 就在线编辑吧
  • R语言系统教程(一):向量及其相关操作

    R语言系统教程 一 向量及其相关操作 前言 1 1 向量 Vector 赋值 1 10 4 5 6 3 1 6 4 21 7 运算 常用函数 1 2 Generate常用向量 Vector 等差数列 等间隔函数 重复函数 1 3 逻辑向量
  • coco 输出格式,MPII 输出格式,标注

    pose 1 数据集 coco 输出格式 MPII 输出格式 代码 详解 1 2 blobFromImage函数 1 数据集 BODY25 COCO MPI coco 输出格式 鼻子 0 颈部 1 右肩 2 右肘 3 右手腕 4 左肩 5
  • 阿里无影云电脑 试用评测

    总有些一些项目需要在家里和公司两头做 不管是用 svn git 云盘同步 还是U盘拷贝都是很麻烦的 背笔记本更累 以前一直想买个挂机宝 但那玩意的配置实在是低 又想说买个云电脑 玩游戏的那种 但价格贵的离谱 一直用vps将就 那性能大家都知
  • Java Collections.list()方法具有什么功能呢?

    转自 Java Collections list 方法具有什么功能呢 下文笔者讲述Collections list 方法的功能简介说明 如下所示 Collections list 方法的功能 将参数中的值转换为一个list对象 Collec
  • 主成分分析(PCA)方法原理介绍

    原文链接 http blog codinglabs org articles pca tutorial html
  • ElasticSearch 设置(一)发现和集群形成

    文章目录 发现和集群形成 发现 种子节点提供者 基于配置的种子主机提供者 基于文件的种子主机提供者 基于法定人数的选举 主节点的选举 投票配置 偶数个符合主节点的节点 设置初始投票配置 引导一个集群 选择集群名称 发布集群状态 集群故障检测
  • 分库分表ShardingSphere<三> _ 分布式事务

    目录 一 分布式事务 1 LOCAL事务 2 XA事务 3 BASE事务 柔性事务 二 示例 1 依赖jar包 2 配置XA事务 3 使用XA事务 三 参考资料 一 分布式事务 ShardingSphere提供三种事务类型 LOCAL 默认
  • MySQL之DML操作

    MySQL之DML操作 1 什么是DML操作 2 插入记录 insert 3 更新记录 update 4 删除记录 delete 1 什么是DML操作 DML是指数据操作语言 英文全称是Data Manipulation Language
  • 最难以理解的排序算法 - 堆排序(超详解)

    堆排序基本介绍 堆排序是利用堆这种数据结构而设计的一种排序算法 堆排序是一种选择排序 它的最坏 最好 平均时间复杂度均为O nlogn 它也是不稳定排序 要理解堆排序 必须先要理解堆这种数据结构 堆是具有以下性质的完全二叉树 每个结点的值都
  • Java 数据结构之双向链表

    版权声明 本文为博主原创文章 未经博主允许不得转载 https blog csdn net lovoo article details 51771321 一 概述 1 什么时双向链表 链表中的每个节点即指向前面一个节点 也指向后面一个节点