首页 > 编程语言 >Java实现双向循环链表

Java实现双向循环链表

时间:2022-11-21 09:11:35浏览次数:39  
标签:Node getNext Java target ll public 链表 双向 节点

上一篇文章实现了单向循环链表,双向很简单,在单向循环链表的基础上加一个前驱指针,

节点类如下:

/**
 * 双向链表节点
 */
public class Node
{
    private int data;//数据域
    private Node pre;//指向上一个节点
    private Node next;//指向下一个节点

    public int getData() {
        return data;
    }
    public void setData(int data) {
        this.data = data;
    }
    public Node getPre() {
        return pre;
    }
    public void setPre(Node pre) {
        this.pre = pre;
    }
    public Node getNext() {
        return next;
    }
    public void setNext(Node next) {
        this.next = next;
    }

    //构造函数
    public Node(int data, Node pre, Node next){
        this.data = data;
        this.pre = pre;
        this.next = next;
    }
    public Node(int data){
        this(data,null,null);
    }
    public Node(){
        this(0,null,null);
    }

}

具体实现:

  1 /**
  2  * Java实现双向循环链表
  3  * Author:hangwei
  4  * 2022/11
  5  */
  6 public class DLinkedList {
  7     private Node head;
  8     private Node tail;
  9     private int size;
 10     public Node getHead() {
 11         return head;
 12     }
 13     public Node getTail() {
 14         return tail;
 15     }
 16     public DLinkedList(){
 17         tail = head = null;
 18         size = 0;
 19     }
 20 
 21     /**
 22      * 在双向循环链表的任意位置之后新增一个节点
 23      * @param position 新增的位置,即新增节点的上一个节点
 24      * @param target 新增节点
 25      */
 26     public void addNode(Node position,Node target){
 27         if(target == null)
 28             return;
 29         if (size == 0) {
 30             target.setPre(target);
 31             target.setNext(target);
 32             tail = head = target;
 33         } else if (position == null) {//position为空就在链表尾部添加新节点
 34             tail.setNext(target);//尾节点的下一个节点是新节点
 35             target.setPre(tail);//新节点的上一个节点是尾节点
 36             target.setNext(head);//新节点的下一个节点是头节点
 37             //标记新的尾节点
 38             tail = target;
 39         } else {
 40             target.setPre(position);
 41             target.setNext(position.getNext());//原来position节点的下一个节点变成target的下一个节点
 42             position.setNext(target);
 43             if(size == 1 || position == tail)//标记新的尾节点
 44                 tail = target;
 45         }
 46         size++;
 47     }
 48 
 49     /**
 50      * 删除链表中的任意节点
 51      * @param target 即将被删除的节点
 52      */
 53     public void deleteNode(Node target){
 54         if(size == 0 || target == null){
 55             System.out.println("null linked list ,can not delete.");
 56             return;
 57         }
 58         else if(size == 1){
 59             head = tail = null;
 60         }
 61         else {
 62             if(target == head){//如果目标是头节点
 63                 head.getNext().setPre(tail);
 64                 tail.setNext(head.getNext());
 65                 head = head.getNext();
 66             }
 67             else {
 68                 //计算目标节点的上一个节点
 69 /*                Node n = new Node();//n表示target节点的上一个节点
 70                 n = head;
 71                 while (n.getNext() != tail) {//可以看到这里:当想要求解单向链表中的某个非头/尾节点时始终涉及到遍历
 72                     if (n.getNext() == target)
 73                         break;
 74                     n = n.getNext();
 75                 }*/
 76                 Node n = target.getPre();//双向循环链表这里不用计算上一个节点
 77                 target.getNext().setPre(n);
 78                 n.setNext(target.getNext());
 79                 if(target == tail)//如果目标是尾节点
 80                     tail = n;//标记新的尾节点
 81             }
 82         }
 83         size--;
 84     }
 85 
 86     //打印链表
 87     public void print(){
 88         Node node = new Node();
 89         node = head;
 90         while (node.getNext() != head && node.getNext() != null){//遍历
 91             System.out.print(node.getData());
 92             System.out.print("<->");
 93             node = node.getNext();
 94         }
 95         System.out.print(node.getData());//补充打印循环体的最后一个节点
 96         System.out.print("<->");
 97         //最后打印出头节点
 98         System.out.print(head.getData());
 99         System.out.println();
100     }
101 }
View Code

测试类:

public class Main {
    public static void main(String[] args) {
        //测试双向循环链表
        DLinkedList ll = new DLinkedList();
        ll.addNode(null,new Node(0));
        ll.print();
        ll.addNode(null,new Node(1));
        ll.addNode(null,new Node(2));
        ll.addNode(null,new Node(3));
        ll.print();
        ll.addNode(ll.getHead().getNext(),new Node(4));
        ll.print();
        ll.deleteNode(ll.getHead().getNext().getNext());
        ll.print();
        ll.deleteNode(ll.getHead());
        ll.print();
        ll.deleteNode(ll.getTail().getPre());
        ll.print();
    }
}

执行结果:

 

 

*重点:相比单向链表,双向链表的优点:不需要通过遍历(O(n))来查找某个节点的上一个节点。

 

标签:Node,getNext,Java,target,ll,public,链表,双向,节点
From: https://www.cnblogs.com/hangwei/p/16910258.html

相关文章

  • JavaScript基础快速复习
    目录学习信息01初识JavaScript浏览器执行JS过程JS的组成JS初体验JS的注释02JavaScript输入输出语句03变量变量概述变量的使用变量的语法扩展变量的命名规范04数......
  • 【java技术总结】编码总结
    java中的编解码1.ISO-8859-1单字节编码收录的字符除ASCII收录的字符外,还包括西欧语言、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号。2.gb2312变长1-2字节GB......
  • JavaSE
    Java基础JDK(JavaDevelopmentKit)Java开发工具包JRE(JavaRuntimeEnvironment)Java运行环境JVM(JavaVirtualMachine)Java虚拟机\[\begin{array}{l}JDK&=......
  • 【java技术总结】将中文通过ISO-8859-1方式编码传输
    在Java中,String的getBytes()方法是得到一个操作系统默认的编码格式的字节数组。这个表示在不同情况下,返回的东西不一样!String.getBytes(Stringdecode)方法会根据指定的de......
  • 在java中new一个对象的流程是什么?
    Dogdog=newDog()背后执行过程这个涉及到字节码文件结构,类加载机制,堆,栈的认识等知识点。在执行new的时候可以大致分为二个过程,初始化以及实例化,初始化就是类的加载过程,......
  • Java高手请进:关于接口的问题。
    《鲁提辖剃度》和尚要做什么呢,要吃斋(chiZai())、念经(nianJing())、打坐(daZuo())、撞钟(zhuangZhong())、习武(xiWu())等。如果设计一个和尚(Monk)接口,给出所有和尚都需要实现的方法,那么这个接......
  • Java中使用javassist库动态操作类
    它是一个用来处理Java字节码的类库,也就是说没有.java文件,用它可以直接造一个.class文件。直接创建一个class类例如:importjavassist.*;/***使用javassist库*/......
  • 新手随笔java+cpp
    随便写写关于java和cpp感悟·1.初学java(在学ing),学了几个月cpp(也不算熟练,但是目前比java好点)·2.java应该是更灵活的,比如【一些灵活点和区别】,二维数组不是非要矩阵形......
  • javascript - 练习题:事件练习 - 贪吃蛇
    贪吃蛇原生JS(非面向对象的方式),渡一教学的笔记;地图坐标{0,0}{1,0}{2,0}{3,0}{4,0}{0,1}{1,1}{2,1}{3,1}{4,1}{0,2}{1,2}{2,2}{3,2}{4,2}{0,3}{1,3}{2,3}{3,3}{4,3}{0,4}{1,4}......
  • java-网络编程
    一、概述1、两个主要问题(1)如何准确定位网络上一台或多台主机;定位主机上的特定应用(2)找到主机后如何可靠高效的进行数据传输2、两个要素(1)IP和端口号(2)网络通信协议(OSI参......