zoukankan      html  css  js  c++  java
  • java数据结构——单链表、双端链表、双向链表(Linked List)

    1、继续学习单链表,终于摆脱数组的魔爪了,单链表分为数据域(前突)和引用域(指针域)(后继),还有一个头结点(就好比一辆火车,我们只关心火车头,不关心其它车厢,只需知晓车头顺藤摸瓜即可),头结点没有前突,尾结点没有后继,注意不是前仆后继。  

     1 public class Node {//包装车厢
     2     /**
     3      * 人无完人,如有bug,还请斧正
     4      */
     5     public long data;// 数据域
     6     public Node next;// 指针域,后指针
        public Node previous;// 指针域,前指针
    7 8 public Node(long value) {// 构造函数 9 this.data = value; 10 } 11 12 public void display() { 13 System.out.print(data + " "); 14 } 15 }
     1 //单链表,头结点插入
     2 public class LinkList {
     3     private Node first;// 火车头,保存头结点的一个指向
     4 
     5     public LinkList() {// 初始化
     6         first = null;
     7     }
     8 
     9     public static void main(String[] args) {
    10         LinkList ll = new LinkList();
    11         ll.insert(4);// 添加
    12         ll.insert(57);
    13         ll.insert(32);
    14         ll.insert(68);
    15 
    16         ll.display();// 先进后出
    17 
    18         ll.delete(32);// 删除32
    19         System.out.println("");
    20         System.out.println("--------");
    21         ll.display();
    22 
    23         System.out.println("");
    24         System.out.println("--------");
    25 
    26         ll.deleteFirst();// 删除头结点
    27         ll.display();
    28 
    29         System.out.println("");
    30         System.out.println("--------");
    31         Node node = ll.find(4);// 查找4
    32         node.display();
    33     }
    34 
    35     public Node deleteFirst() {// 删除头结点
    36         first = first.next;// 头结点为头结点的下一个
    37         return first;
    38     }
    39 
    40     public Node find(long value) {// 按值查找,返回null或索引值
    41         Node current = first;// 从头结点开始
    42 
    43         while (current.data != value) {
    44 
    45             if (current.next == null) {// 尾结点后继为null
    46                 return null;
    47             }
    48             current = current.next;
    49         }
    50         return current;// 找到返回
    51     }
    52 
    53     public Node delete(long value) {// 删除任意结点
    54         Node current = first;
    55         Node previous = first;
    56 
    57         while (current.data != value) {
    58             if (current.next == null) {// 没有找到
    59                 return null;
    60             }
    61             previous = current;// 保存邻近的两个结点
    62             current = current.next;
    63         }
    64 
    65         if (current == first) {// 第一个结点
    66             first = first.next;
    67         } else {// 后面的结点
    68             previous.next = current.next;// 上一个结点的下一个变为当前结点的下一个,当前结点删除
    69         }
    70         return current;// 结点类,返回结点类型
    71     }
    72 
    73     public void insert(long value) {// 在头结点之后插入
    74         Node node = new Node(value);// 创建新的结点
    75         // 这里深深体会一下精妙之处,first保存着一个指向
    76         node.next = first;// 图示第一步
    77         first = node;// 图示第二步
    78     }
    79 
    80     public void display() {// 显示
    81         Node current = first;
    82         while (current != null) {
    83             current.display();
    84             current = current.next;
    85         }
    86     }
    87 }
    单链表

     单链表时只能实现头部依次插入数据,为了弥补这个局限性,所以我们得学习双端链表,即链表中保存着对最后一个链结点引用的链表。

    2、双端链表

      1 //双端链表,头尾结点都可以插入
      2 public class FirstLastLinkList {
      3     private Node first;// 火车头,保存头结点的一个指向第一个node
      4     private Node last;// 火车尾,保存头结点的一个指向最后一个node
      5 
      6     public FirstLastLinkList() {
      7         first = null;
      8     }
      9 
     10     public static void main(String[] args) {
     11         FirstLastLinkList fll = new FirstLastLinkList();
     12 
     13         fll.insertLast(26);
     14         fll.insertLast(24);
     15         fll.insertLast(65);
     16         fll.insertLast(17);
     17         fll.display();// 先进先出
     18 
     19         System.out.println("");
     20         System.out.println("--------");
     21 
     22         fll.deleteFirst();
     23         fll.display();
     24 
     25         System.out.println("");
     26         System.out.println("--------");
     27     }
     28 
     29     public Node deleteFirst() {// 删除头结点
     30         if (first.next == null) {
     31             last = null;// 没有结点
     32         }
     33         first = first.next;
     34         return first;
     35     }
     36 
     37     public Node find(long value) {// 查找
     38         Node current = first;
     39 
     40         while (current.data != value) {
     41 
     42             if (current.next == null) {
     43                 return null;
     44             }
     45             current = current.next;
     46         }
     47         return current;
     48     }
     49 
     50     public Node delete(long value) {// 删除任意结点
     51         Node current = first;
     52         Node previous = first;
     53 
     54         while (current.data != value) {
     55             if (current.next == null) {// 没有找到
     56                 return null;
     57             }
     58             previous = current;
     59             current = current.next;
     60         }
     61 
     62         if (current == first) {// 第一个结点
     63             first = first.next;
     64         } else {// 后面的结点
     65             previous.next = current.next;
     66         }
     67         return current;
     68     }
     69 
     70     public void insert(long value) {// 在头结点插入
     71         Node node = new Node(value);// 创建新的结点
     72         if (isEmpty()) {
     73             last = node;
     74         }
     75         node.next = first;
     76         first = node;
     77     }
     78 
     79     public void insertLast(long value) {// 在尾结点插入
     80         Node node = new Node(value);
     81         if (isEmpty()) {// 为空
     82             first = node;
     83         } else {// 不为空
     84             last.next = node;// 图示1
     85         }
     86         last = node;// 图示2
     87     }
     88 
     89     public boolean isEmpty() {// 是否空
     90         return first == null;
     91     }
     92 
     93     public void display() {// 显示
     94         Node current = first;
     95         while (current != null) {
     96             current.display();
     97             current = current.next;
     98         }
     99     }
    100 }
    双端链表

    3、双向链表,Node就会多一个属性previous,每个结点除了保存对下一个结点的引用,同时还保存着对前一个结点的引用。

      1 //双向链表,头尾结点都可以插入和删除
      2 public class DoubleLinkList {
      3     private Node first;// 火车头
      4     private Node last;// 火车尾
      5 
      6     public DoubleLinkList() {
      7         first = null;
      8     }
      9 
     10     public static void main(String[] args) {
     11         DoubleLinkList dll = new DoubleLinkList();
     12         dll.insertLast(342);
     13         dll.insertLast(54);
     14         dll.insertLast(24);
     15         dll.display();
     16 
     17         System.out.println("");
     18         System.out.println("--------");
     19 
     20         while (!dll.isEmpty()) {
     21             dll.deleteFirst();
     22             dll.display();
     23             System.out.println("");
     24             System.out.println("--------");
     25         }
     26 
     27         System.out.println("");
     28         System.out.println("--------");
     29 
     30         System.out.println("");
     31         System.out.println("--------");
     32     }
     33 
     34     public Node deleteFirst() {// 从头结点开始删除
     35         if (first.next == null) {// 判断头结点是否有下一个结点
     36             last = null;// 没有结点
     37         } else {
     38             first.next.previous = null;// 设置头结点的下一个结点的previous为null
     39         }
     40         first = first.next;
     41         return first;
     42     }
     43 
     44     public Node deleteLast() {// 从尾结点开始删除
     45         if (first.next == null) {// 头结点后面没有其它结点,当前为最后一个结点
     46             first = null;
     47         } else {
     48             last.previous.next = null;// 设置尾结点的前一个结点的next为null
     49         }
     50         last = last.previous;
     51         return last;
     52     }
     53 
     54     public Node find(long value) {// 查找
     55         Node current = first;
     56 
     57         while (current.data != value) {
     58 
     59             if (current.next == null) {
     60                 return null;
     61             }
     62             current = current.next;
     63         }
     64         return current;
     65     }
     66 
     67     public Node delete(long value) {// 删除任意结点
     68         Node current = first;
     69         // 不需要临时的指针域
     70         while (current.data != value) {
     71             if (current.next == null) {// 没有找到
     72                 return null;
     73             }
     74             current = current.next;
     75         }
     76         if (current == first) {// 第一个结点
     77             first = first.next;
     78         } else {// 后面的结点
     79             current.previous.next = current.next;
     80         }
     81         return current;
     82     }
     83 
     84     public void insert(long value) {// 在头结点之后插入
     85         Node node = new Node(value);// 创建新的结点
     86         if (isEmpty()) {// 要对链表进行判断,为空则设置尾结点为新添加的结点
     87             last = node;
     88         } else {
     89             first.previous = node;// 不为空,需要设置头结点前一个结点为新添加的结点
     90         }
     91         node.next = first;
     92         first = node;
     93     }
     94 
     95     public void insertLast(long value) {// 在尾结点之后插入
     96         Node node = new Node(value);// 创建新的结点
     97         if (isEmpty()) {// 为空,直接设置头结点为新添加的结点
     98             first = node;
     99         } else {
    100             last.next = node;// 设置尾结点的后一个结点为新添加的结点,
    101         }
    102         node.previous = last;// 新添加的前一个结点为新添加的结点
    103         last = node;
    104     }
    105 
    106     public boolean isEmpty() {// 是否空
    107         return first == null;
    108     }
    109 
    110     public void display() {// 显示
    111         Node current = first;
    112         while (current != null) {
    113             current.display();
    114             current = current.next;
    115         }
    116     }
    117 }
    双向链表

    删除后JVM自动回收垃圾

  • 相关阅读:
    bzoj 4012: [HNOI2015]开店
    POJ 1054 The Troublesome Frog
    POJ 3171 Cleaning Shifts
    POJ 3411 Paid Roads
    POJ 3045 Cow Acrobats
    POJ 1742 Coins
    POJ 3181 Dollar Dayz
    POJ 3040 Allowance
    POJ 3666 Making the Grade
    洛谷 P3657 [USACO17FEB]Why Did the Cow Cross the Road II P
  • 原文地址:https://www.cnblogs.com/hardhp74520/p/11306720.html
Copyright © 2011-2022 走看看