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 数据结构之双向链表 的相关文章

随机推荐

  • 跨域问题的原理分析

    一 什么是跨域 当页面来源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 什么时双向链表 链表中的每个节点即指向前面一个节点 也指向后面一个节点