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

 

posted @ 2019-08-06 08:14  hardhp74520  阅读(450)  评论(0编辑  收藏  举报