• java 链表 单向 双向


    Java-链表

    1、什么是链表?

    2、链表的特点是什么?

    3、链表的实现原理?

    4、如何自己写出一个链表?


    1、什么是链表?

    • 链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针连接次序实现的。
    • 每一个链表都包含多个节点,节点又包含两个部分,一个是数据域(储存节点含有的信息),一个是引用域(储存下一个节点或者上一个节点的地址)。
    • 链表的理解示意图

    2、链表的特点是什么?

    • 获取数据麻烦,需要遍历查找,比数组慢
    • 方便插入、删除

    3、链表的实现原理

    1. 创建一个节点类,其中节点类包含两个部分,第一个是数据域(你到时候要往节点里面储存的信息),第二个是引用域(相当于指针,单向链表有一个指针,指向下一个节点;双向链表有两个指针,分别指向下一个和上一个节点)
    2. 创建一个链表类,其中链表类包含三个属性:头结点、尾节点和大小,方法包含添加、删除、插入等等方法。

    单向链表的节点类:

    复制代码
    1 public class Node {
    2     public Object data;
    3     public Node next;
    4     
    5     public Node(Object e){
    6         this.data = e;
    7     }
    8 }
    复制代码

    双向链表的节点类:

    复制代码
     1 public class Node {
     2     public Object e;
     3     public Node next;
     4     public Node pre;
     5     public Node(){
     6 
     7     }
     8     public Node(Object e){
     9         this.e = e;
    10         next = null;
    11         pre = null;
    12     }
    13 }
    复制代码

    4、如何自己写出一个链表?

    代码如下(以双向链表为例,有详细的注释,单向链表同理):

    首先创建了一个节点类

    复制代码
     1 package MutuLink;
     2 
     3 public class Node {
     4     public Object e;
     5     public Node next;
     6     public Node pre;
     7     public Node(){
     8 
     9     }
    10     public Node(Object e){
    11         this.e = e;
    12         next = null;
    13         pre = null;
    14     }
    15 }
    复制代码

    然后创建了一个链表类

    复制代码
      1 package MutuLink;
      2 
      3 public class MyList {
      4     private Node head;
      5     private Node tail;
      6     private int size = 0;
      7 
      8     public MyList() {
      9         head = new Node();
     10         tail = new Node();
     11         head.next =null;
     12         tail.pre = null;
     13     }
     14 
     15     public boolean empty() {
     16         if (head.next == null)
     17             return true;
     18         return false;
     19     }
     20     //找到所找下标节点的前一个节点
     21     public Node findpre(int index){
     22         Node rnode = head;
     23         int dex = -1;
     24         while(rnode.next != null){
     25             //找到了插入节点的上一个节点
     26             if( dex== index - 1){
     27                 return rnode;
     28             }
     29             rnode = rnode.next;
     30             dex++;
     31         }
     32         return null;
     33     }
     34     public Node findthis(int index){
     35         Node rnode = head;
     36         //把rnode想象为指针,dex为指向的下标,这个地方很容易错,因为当指向最后一个节点时没有判断IF就跳出循环了
     37         int dex = -1;
     38         while(rnode.next != null){
     39             if(dex == index)
     40             return rnode;
     41             rnode = rnode.next;
     42             dex++;
     43         }
     44         if(dex == size - 1){
     45             return rnode;
     46         }
     47 //        Node test = new Node(new Students("haha",1,2));
     48         return null;
     49     }
     50 
     51     // 往链表末尾加入节点
     52     public void add(Object e) {
     53         Node node = new Node(e);
     54         Node rnode = head;
     55         //如果是空链表的话插入一个节点,这个节点的pre不能指向上一个节点,必须指空
     56         if (this.empty()) {
     57             rnode.next = node;
     58             rnode.next.pre = null;
     59             tail.pre = node;
     60             size++;
     61         } else {
     62             while (rnode.next != null)
     63                 rnode = rnode.next;
     64             rnode.next = node;
     65             node.pre = rnode;
     66             tail.pre = node;
     67             size++;
     68         }
     69     }
     70     //往链表的某一个标插入一个节点
     71     public boolean add(int index,Object e){
     72         if(index <0||index>=size)
     73             return false;
     74         Node node = new Node(e);
     75         Node prenode = this.findpre(index);
     76         node.next = prenode.next;
     77         prenode.next.pre = node;
     78         prenode.next = node;
     79         node.pre = prenode;
     80         size++;
     81         return true;
     82     }
     83     public boolean add(int index,MyList myl){
     84         if(index <0 || index >= size)
     85             return false;
     86         Node prenode = this.findpre(index);
     87 //        myl.tail.pre.next = prenode.next;
     88 //        prenode.pre = myl.tail.pre;
     89 //        tail.pre = null;
     90 //        prenode.next = myl.head.next;
     91 //        myl.head.next.pre = prenode;
     92 //        head.next = null;
     93         myl.tail.pre.next = prenode.next;
     94         prenode.next.pre = myl.tail.pre.pre;
     95         myl.head.next.pre = prenode.pre;
     96         prenode.next = myl.head.next;
     97         myl.head = null;
     98         myl.tail = null;
     99         size+=myl.size;
    100         return true;
    101     }
    102     
    103     public Object remove(int index){
    104         Object ob= this.get(index);
    105         if(index <0 || index >= size)
    106             return null;
    107         //特殊情况,当移除节点是最后一个节点的时候
    108         //较为复杂通过画图来写代码
    109         if(index == size - 1){
    110             Node prenode = this.findpre(index);
    111             this.tail.pre = this.tail.pre.pre;
    112             this.tail.pre.next.pre = null;
    113             this.tail.pre.next =null;
    114             size--;
    115             return ob;
    116         }
    117         //比较复杂,通过画图解决
    118         else{
    119             Node prenode = this.findpre(index);
    120             prenode.next = prenode.next.next;
    121             prenode.next.pre.next = null;
    122             prenode.next.pre = prenode.next.pre.pre;
    123             size--;
    124             return ob;
    125         }
    126     }
    127     
    128     
    129     public Object get(int index){
    130         Node thisnode = this.findthis(index);
    131         return thisnode.e;
    132     }
    133     public int size(){
    134         return size;
    135     }
    136 }
    复制代码

    最后测试

    复制代码
     1 package MutuLink;
     2 
     3 import java.util.Random;
     4 
     5 public class manage {
     6     public static void main(String[] args) {
     7         String name = "";
     8         int credit;
     9         int age;
    10         int size;
    11         MyList myl = new MyList();
    12         Random random = new Random();
    13         size = random.nextInt(5) + 1;
    14         for (int i = 0; i < size; i++) {
    15             credit = random.nextInt(5);
    16             age = random.nextInt(5) + 18;
    17             for (int j = 0; j < 4; j++) {
    18                 name += (char) (random.nextInt(26) + 97);
    19             }
    20             Students stu = new Students(name, credit, age);
    21             myl.add(stu);
    22             name = "";
    23         }
    24 
    25         System.out.println("Size of myl1 is "+ myl.size());
    26         for(int i = 0; i < myl.size() ;i++){
    27             Students stu2 = (Students) myl.get(i);
    28             stu2.show();
    29         }
    30 //        //测试能否在链表末尾加入节点(成功)
    31 //        for(int i = 0; i < myl.size() ;i++){
    32 //            Students stu2 = (Students) myl.get(i);
    33 //            stu2.show();
    34 //        }
    35 //        //测试能否通过下标加入一个节点(成功)
    36 //        Students stu3 = new Students("cyt",5,18);
    37 //        myl.add(1, stu3);
    38 //        System.out.println("Size is "+ myl.size());
    39 //        for(int i = 0; i < myl.size() ;i++){
    40 //            Students stu2 = (Students) myl.get(i);
    41 //            stu2.show();
    42 //        }
    43 
    44         MyList myl2 = new MyList();
    45         size = random.nextInt(5) + 1;
    46         for (int i = 0; i < size; i++) {
    47             credit = random.nextInt(5);
    48             age = random.nextInt(5) + 18;
    49             for (int j = 0; j < 4; j++) {
    50                 name += (char) (random.nextInt(26) + 97);
    51             }
    52             Students stu2 = new Students(name, credit, age);
    53             myl2.add(stu2);
    54             name = "";
    55         }
    56         System.out.println("Size is of myl2 "+ myl2.size());
    57         for(int i = 0; i < myl2.size() ;i++){
    58             Students stu2 = (Students) myl2.get(i);
    59             stu2.show();
    60         }
    61 
    62 
    63         
    64         myl.add(1, myl2);
    65         System.out.println("Size is of myl1 "+ myl.size());
    66         for(int i = 0; i < myl.size() ;i++){
    67             Students stu2 = (Students) myl.get(i);
    68             stu2.show();
    69         }
    70         
    71         
    72     }
    73 
    74 }
    复制代码

    结果输出:

     这样,一个简单的双向链表就编写完成了,希望这篇博客对您有所帮助哦!

  • 相关阅读:
    Java 数组算法列题解析
    Java数组总结
    go实现汉诺塔
    go实现归并排序
    css清除浮动深度解析
    jquery阻止事件冒泡
    java
    getComputedStyle/currentStyle/style之间的爱恨情仇
    js基础总结
    元素堆叠问题、z-index、position
  • 原文地址:https://www.cnblogs.com/cfas/p/15966468.html
Copyright © 2020-2023  润新知