• 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自动回收垃圾

  • 相关阅读:
    问题解决:System.TypeLoadException: 未能从程序集“XXX”中加载类型“XXX
    域名格式验证
    .NET 中String 和StringBuilder 以及他们的区别
    mysql 重设管理员密码 或忘记管理员密码 (必杀)
    CMD 命令
    C# 给多线程传参的三种方式
    django 表单数据的验证实现原理
    django上传文件
    django signal
    Django如何处理语言偏好(根据此可以设置中文)
  • 原文地址:https://www.cnblogs.com/hardhp74520/p/11306720.html
Copyright © 2020-2023  润新知