Java实现双链表的示例代码

目录
  • 一、双向链表是什么
  • 二、具体方法实现
    • 定义结点
    • 下标访问异常
    • 获取链表长度
    • 打印链表
    • 清空链表
    • 头插法
    • 尾插法
    • 指定位置插入
    • 查找元素
    • 删除第一次出现的关键字
    • 删除所有值为key的节点
  • 三、完整代码

一、双向链表是什么

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。

LinkedList底层就是一个双向链表,我们来实现一个双向链表。

这里多一个尾指针,方便我们对尾插操作从O(n)降到O(1).每个结点多了前驱结点,方便我们对链表进行操作。

二、具体方法实现

定义结点

class ListNode {
        int value;
        ListNode next;
        ListNode prev;

        public ListNode(int value) {
            this.value = value;
        }
    }

下标访问异常

public class IndexWrongException extends RuntimeException{
    public IndexWrongException() {
    }

    public IndexWrongException(String message) {
        super(message);
    }
}

获取链表长度

class ListNode {
        int value;
        ListNode next;
        ListNode prev;

        public ListNode(int value) {
            this.value = value;
        }
    }

打印链表

class ListNode {
        int value;
        ListNode next;
        ListNode prev;

        public ListNode(int value) {
            this.value = value;
        }
    }

清空链表

public void clear(){
        if(this.head == null) {
            return;
        }
        ListNode cur = this.head;
        while(cur != null) {
            ListNode curNext = cur.next;
            cur.prev = null;
            cur.next = null;
            cur = curNext;
        }
        head = null;
        tail = null;
    }

头插法

public void addFirst(int data){
        ListNode node = new ListNode(data);
        if(head == null) {
            this.head = node;
            this.tail = node;
            return;
        }
        node.next = this.head;
        this.head.prev = node;
        this.head = node;
    }

尾插法

public void addLast(int data){
        ListNode node = new ListNode(data);
        if(head == null) {
            this.head = node;
            this.tail = node;
            return;
        }
        tail.next = node;
        node.prev = tail;
        tail = node;
    }

指定位置插入

public void addIndex(int index,int data) throws IndexWrongException{
        if(index < 0 || index > size()) {
            throw new IndexWrongException("输入下标不合法");
        }
        ListNode node = new ListNode(data);
        if(index == 0) {
            addFirst(data);
            return;
        }
        if(index == size()) {
            addLast(data);
            return;
        }
        ListNode cur = this.head;
        while(index != 0) {
            cur = cur.next;
            index--;
        }
        node.next = cur;
        cur.prev.next = node;
        node.prev = cur.prev;
        cur.prev = node;
    }

查找元素

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

删除第一次出现的关键字

public void remove(int key){
        ListNode cur = head;
        while(cur != head) {
            if(cur.value == key) {
                if(cur == head) {
                    head = head.next;
                    if(head.next != null) {
                        head.prev = null;
                    }else {
                        tail = null;
                    }
                }else {
                    cur.prev.next = cur.next;
                    if(cur.next != null) {
                        cur.next.prev = cur.prev;
                    }else {
                        tail = cur.prev;
                        tail.next = null;
                        }
                    }
                return;
                }
            cur = cur.next;
            }
        }

删除所有值为key的节点

public void removeAllKey(int key){
        ListNode cur = head;
        while(cur != head) {
            if(cur.value == key) {
                if(cur == head) {
                    head = head.next;
                    if(head.next != null) {
                        head.prev = null;
                    }else {
                        tail = null;
                    }
                }else {
                    cur.prev.next = cur.next;
                    if(cur.next != null) {
                        cur.next.prev = cur.prev;
                    }else {
                        tail = cur.prev;
                        tail.next = null;
                    }
                }
            }
            cur = cur.next;
        }
    }

三、完整代码

public class LinkedList {
    static class ListNode {
        int value;
        ListNode next;
        ListNode prev;

        public ListNode(int value) {
            this.value = value;
        }
    }
    ListNode head;
    ListNode tail;
    //头插法
    public void addFirst(int data){
        ListNode node = new ListNode(data);
        if(head == null) {
            this.head = node;
            this.tail = node;
            return;
        }
        node.next = this.head;
        this.head.prev = node;
        this.head = node;
    }
    //尾插法
    public void addLast(int data){
        ListNode node = new ListNode(data);
        if(head == null) {
            this.head = node;
            this.tail = node;
            return;
        }
        tail.next = node;
        node.prev = tail;
        tail = node;
    }
    //任意位置插入,第一个数据节点为0号下标
    public void addIndex(int index,int data) throws IndexWrongException{
        if(index < 0 || index > size()) {
            throw new IndexWrongException("输入下标不合法");
        }
        ListNode node = new ListNode(data);
        if(index == 0) {
            addFirst(data);
            return;
        }
        if(index == size()) {
            addLast(data);
            return;
        }
        ListNode cur = this.head;
        while(index != 0) {
            cur = cur.next;
            index--;
        }
        node.next = cur;
        cur.prev.next = node;
        node.prev = cur.prev;
        cur.prev = node;
    }
    //查找是否包含关键字key是否在单链表当中
    public boolean contains(int key){
        if(head == null) {
            return false;
        }
        ListNode cur = this.head;
        while(cur != null) {
            if(cur.value == key) {
                return true;
            }
            cur = cur.next;
        }
        return false;
    }
    //删除第一次出现关键字为key的节点
    public void remove(int key){
        ListNode cur = head;
        while(cur != head) {
            if(cur.value == key) {
                if(cur == head) {
                    head = head.next;
                    if(head.next != null) {
                        head.prev = null;
                    }else {
                        tail = null;
                    }
                }else {
                    cur.prev.next = cur.next;
                    if(cur.next != null) {
                        cur.next.prev = cur.prev;
                    }else {
                        tail = cur.prev;
                        tail.next = null;
                        }
                    }
                return;
                }
            cur = cur.next;
            }
        }
    //删除所有值为key的节点
    public void removeAllKey(int key){
        ListNode cur = head;
        while(cur != head) {
            if(cur.value == key) {
                if(cur == head) {
                    head = head.next;
                    if(head.next != null) {
                        head.prev = null;
                    }else {
                        tail = null;
                    }
                }else {
                    cur.prev.next = cur.next;
                    if(cur.next != null) {
                        cur.next.prev = cur.prev;
                    }else {
                        tail = cur.prev;
                        tail.next = null;
                    }
                }
            }
            cur = cur.next;
        }
    }
    //得到单链表的长度
    public int size(){
        ListNode cur = head;
        int count = 0;
        while(cur != null) {
            cur = cur.next;
            count++;
        }
        return count;
    }
    public void display(){
        ListNode cur = head;
        while (cur != null) {
            System.out.print(cur.value+" ");
            cur = cur.next;
        }
        System.out.println();
    }
    public void clear(){
        if(this.head == null) {
            return;
        }
        ListNode cur = this.head;
        while(cur != null) {
            ListNode curNext = cur.next;
            cur.prev = null;
            cur.next = null;
            cur = curNext;
        }
        head = null;
        tail = null;
    }
}

到此这篇关于Java实现双链表的示例代码的文章就介绍到这了,更多相关Java双链表内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • java实现单链表、双向链表

    本文实例为大家分享了java实现单链表.双向链表的相关代码,供大家参考,具体内容如下 java实现单链表: package code; class Node { Node next; int data; public Node(int data) { this.data=data; } } class LinkList { Node first; //头部 public LinkList() { this.first=null; } public void addNode(Node no) {

  • JAVA实现双向链表的增删功能的方法

    JAVA实现双向链表的增删功能,完整代码 package linked; class LinkedTable{ } public class LinkedTableTest { //构造单链表 static Node node1 = new Node("name1"); static Node node2 = new Node("name2"); static Node node3 = new Node("name3"); static Node

  • Java实现双向循环链表

    双向循环链表定义 相比于单链表,有两个指针,next指针指向下一个结点,prior指针指向上一个结点,最后一个结点的next指针指向头结点,头结点的prior指针指向最后一个结点 代码实现: 我们对单链表的实现加以修改 package algorithm.datastructure.doublelinkedlist; import java.util.NoSuchElementException; /* * 双向循环链表 * 两个指针,next指针指向下一个结点,prior指针指向上一个结点,最

  • 基于Java实现双向链表

    本文实例为大家分享了Java实现双向链表的具体代码,供大家参考,具体内容如下 双向链表与单链表的对比: 1.单向链表查找只能是一个方向,双向链表可以向前或者向后查找2.单向链表不能自我删除,需要靠辅助节点**(即需要通过找到要删除的节点的前一个节点,通过该节点进行删除的操作,而双向链表只需找到要删除的节点就行了)**.双向链表可以自我删除 双向链表示意图 分析(代码实现原理):temp为辅助节点(因为头节点不可动)1.遍历:方式与单链表一致,但是是双向的,可以向前,也可以向后2.添加(默认添加到

  • java 实现双向链表实例详解

    java 实现双向链表实例详解 双向链表是一个基本的数据结构,在Java中LinkedList已经实现了这种结构,不过作为开发者,也要拥有自己显示这种结构的能力.话不多说,上代码:     首先是链表的节点类: /** * 链表节点 * @author Administrator * * @param <T> */ public class ChainNode<T> { private T data; //对象编号 private int dataNo; public ChainN

  • Java实现双链表的示例代码

    目录 一.双向链表是什么 二.具体方法实现 定义结点 下标访问异常 获取链表长度 打印链表 清空链表 头插法 尾插法 指定位置插入 查找元素 删除第一次出现的关键字 删除所有值为key的节点 三.完整代码 一.双向链表是什么 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱.所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点.一般我们都构造双向循环链表. LinkedList底层就是一个双向链表,我们来实现一个双向链表. 这

  • Java实现双链表互相交换任意两个节点的方法示例

    本文实例讲述了Java实现双链表互相交换任意两个节点的方法.分享给大家供大家参考,具体如下: 概述: 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱.所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点.一般我们都构造双向循环链表. 思路: 1.确定两个节点的先后顺序 2.next.prev互相交换顺序以及将换向前方的节点与之前的节点对接.(1.prev.next = 2) 3.判断是否相邻 实现代码: 链表类: publi

  • Java实现单链表翻转实例代码

    Java实现单链表反转,递归和非递归两种形式 /** * 反转单链表 */ /** * 定义链表 * * @author 16026 * */ class Node { int val; Node next; public Node(int val) { this.val = val; } } public class ReverseList { /** * 反转链表 * * @param head * @return */ public static Node reverseList(Node

  • Java连接postgresql数据库的示例代码

    本文介绍了Java连接postgresql数据库的示例代码,分享给大家,具体如下: 1.下载驱动jar 下载地址:https://jdbc.postgresql.org/download.html 2.导入jar包 新建lib文件夹,将下载的jar驱动包拖到文件夹中. 将jar驱动包添加到Libraries 3.程序代码如下:HelloWorld.java package test; import java.sql.Connection; import java.sql.DriverManage

  • java 生成文字图片的示例代码

    本文主要介绍了java 生成文字图片的示例代码,分享给大家,具体如下: import java.awt.Color; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO;

  • Java动态规划之编辑距离问题示例代码

    动态规划过程是:每次决策依赖于当前状态,又随即引起状态的转移.一个决策序列就是在变化的状态中产生出来的,所以,这种多阶段最优化决策解决问题的过程就称为动态规划. 动态规划实际上是一类题目的总称,并不是指某个固定的算法.动态规划的意义就是通过采用递推(或者分而治之)的策略,通过解决大问题的子问题从而解决整体的做法.动态规划的核心思想是巧妙的将问题拆分成多个子问题,通过计算子问题而得到整体问题的解.而子问题又可以拆分成更多的子问题,从而用类似递推迭代的方法解决要求的问题.问题描述: 对于序列S和T,

  • Java的静态类型检查示例代码详解

    关于静态类型检查和动态类型检查的解释: 静态类型检查:基于程序的源代码来验证类型安全的过程: 动态类型检查:在程序运行期间验证类型安全的过程: Java使用静态类型检查在编译期间分析程序,确保没有类型错误.基本的思想是不要让类型错误在运行期间发生. 在各色各样的编程语言中,总共存在着两个类型检查机制:静态类型检查和动态类型检查. 静态类型检查是指通过对应用程序的源码进行分析,在编译期间就保证程序的类型安全. 动态类型检查是在程序的运行过程中,验证程序的类型安全.在Java中,编译期间使用静态类型

  • Java随机生成身份证完整示例代码

    身份证算法实现 1.号码的结构 公民身份号码是特征组合码, 由十七位数字本体码和一位校验码组成. 排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码  三位数字顺序码和一位数字校验码. 2.地址码(前六位数) 表示编码对象常住户口所在县(市.旗.区)的行政区划代码,按GB/T2260的规定执行. 3.出生日期码(第七位至十四位) 表示编码对象出生的年.月.日,按GB/T7408的规定执行,年.月.日代码之间不用分隔符. 4.顺序码(第十五位至十七位) 表示在同一地址码所标识的区域范围内,

  • java实现基因序列比较的示例代码

    设计算法,计算两给定基因序列的相似程度. 人类基因由4种核苷酸,分别用字母ACTG表示.要求编写一个程序,按以下规则比较两个基因序列并确定它们的相似程度.即给出两个基因序列AGTGATG和GTTAG,它们有多相似呢?测量两个基因相似度的一种方法称为对齐.使用对齐方法可以在基因的适当位置加入空格,让两个基因的长度相等,然后根据基因的分值矩阵计算分数. 看了很多代码基本上都是用c++或者c写的,但是习惯性写java就用java实现一下 基本的思路就是,和背包问题差不多,实现还是模仿填表的形式去实现的

  • 用java实现跳动的小球示例代码

    实现效果为一个小球接触左右侧时,会反向的运动. import javafx.application.Application; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.paint.Colo

随机推荐