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

Java实现单向循环链表

时间:2022-11-18 18:29:31浏览次数:39  
标签:Node head Java target ll 单向 public 链表 节点

准备节点类,节点类中只有一个int类型的数据域和一个指针:

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

    public int getData() {
        return data;
    }

    public void setData(int data) {
        this.data = data;
    }

    public Node getNext() {
        return next;
    }

    public void setNext(Node next) {
        this.next = next;
    }

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

}

 具体实现:

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

测试类:

public class Test {
    public static void main(String[] args) {
        LinkedList ll = new LinkedList();
        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());
        ll.print();
    }
}

输出结果:

 

*重点:链表在查找节点时涉及的遍历问题(时间复杂度O(n))

 

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

相关文章

  • java8 (jdk 1.8) 新特性——Lambda
    java8(jdk1.8)新特性——初步认识  1.什么是lambda?目前已知的是,有个箭头  ->  说一大段官方话,也没有任何意义我们直接看代码:之前我们创建线程是这样的......
  • Java多线程 CompletionService和ExecutorCompletionService
    (目录)一、说明Future的不足当通过.get()方法获取线程的返回值时,会导致阻塞也就是和当前这个Future关联的计算任务真正执行完成的时候才返回结果新任务必须等待已完......
  • java_slenium_tess4j 简单图片识别
    1.导包2.下载语言库3.代码1》直接识别图片方法一://@parampath:"C:\\Users\\Administrator\\Desktop\\下载\\03.png"publicstaticStringIdentifyCode01(Str......
  • 8. 使Web工程依赖于Java工程
    #在pro02-maven-web工程的pom.xml文件下,添加对pro01-maven-java工程的依赖:(通过坐标) #添加测试代码:##在pro02-maven-web工程的src目录下,添加文件夹:test/java/com/at......
  • kmp算法(Java)
    详解参考:KMP算法讲解next数组求法方式1移动位数=已匹配的字符数-对应的部分匹配值已知空格与D不匹配时,前面六个字符"ABCDAB"是匹配的。查表可知,最后一个匹......
  • java构造方法的作用
    构造方法作用就是对类进行初始化。如果你没有定议任何构造方法的形式,程式会为你取一个不带任何参数的构造函数,那么你产生类的对像时只能用不带参数的方法,如:classa{}//没......
  • JavaScript代码是怎么在浏览器里面运行起来的?
    JavaScript代码是怎么在浏览器里面运行的?下面简单探索一下浏览器内核浏览器内核(RenderingEngine),常见的叫法如:排版引擎、解释引擎、渲染引擎,现在流行称为浏览器内核。......
  • JavaScript_对象_RegExp2与JavaScript_对象_RegExp3
    JavaScript_对象_RegExp2正则对象:1.创建 1.varreg  =new RegExp(“正则表达式”);2.var......
  • java 文件读写操作
    一、BufferedWriter写入文件+BufferedReader读取文件缓冲字符(BufferedWriter)是一个字符流类来处理字符数据。不同于字节流(数据转换成字节),你可以直接写字符串,数组或字符......
  • JavaScript_对象_Math与JavaScript_对象_RegExp1
    JavaScript_对象_MathMath:数学1.创建特点:Math对象不用创建,直接使用。Math.方法名();2.方法random()返回0~1之间的随机数含0不含......