zoukankan      html  css  js  c++  java
  • 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 }

    结果输出:

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

     

  • 相关阅读:
    vue自定义指令
    ZOJ Problem Set–2104 Let the Balloon Rise
    ZOJ Problem Set 3202 Secondprice Auction
    ZOJ Problem Set–1879 Jolly Jumpers
    ZOJ Problem Set–2405 Specialized FourDigit Numbers
    ZOJ Problem Set–1874 Primary Arithmetic
    ZOJ Problem Set–1970 All in All
    ZOJ Problem Set–1828 Fibonacci Numbers
    要怎么样调整状态呢
    ZOJ Problem Set–1951 Goldbach's Conjecture
  • 原文地址:https://www.cnblogs.com/782687539-nanfu/p/10333031.html
Copyright © 2011-2022 走看看