鏈表的簡單原理

線性數據結構

動態數組、棧和隊列,底層都是依託靜態數組,靠resize解決固定容量的問題。(而動態數組之所以叫做動態,是因爲它從用戶的角度來看的,實現它的底層依靠的是靜態數組。)

鏈表與上面的三種線性數據結構都不同,它是真正的動態數據結構

鏈表的重要性

  • 最簡單的動態數據結構
  • 深入理解引用(C/C++中的指針),引用與內存相關
  • 更深入理解遞歸,鏈表本身具有清晰的遞歸結構
  • 具有功能性,組織圖結構,哈希表。

鏈表 Linked List

  • 把數據存儲在一種單獨的結構中,通常叫做“節點”(Node)。
  • 對於鏈表的節點,通常只有兩部分內容
class Node{
	E e;  // 一部分存儲真正的數據
	Node next;  //另一部分,next指向當前節點的下一個節點
}

對於鏈表,可以比作一輛火車,每一個節點是一節車廂,在車廂中存儲真正的數據,車廂與車廂之間需要進行連接使數據是整合在一起的。用戶可以方便的在這些數據上進行查詢等操作,數據與數據之間的連接是由next完成的。

假如第一節車廂存儲元素1,同時它還有一個連接下一節車廂的車鏈(即指向下一個節點的next,是一個Node類型的引用);下一節車廂存儲了元素2,它還有一個next指向下一節車廂;假如下一個節點存儲了元素三,繼續指向下一個節點,這個過程不是無窮無盡的,鏈表存儲的數據一定是有限的。假如火車只有三節車廂,那麼第三節車廂後什麼也沒有,也就是第三個節點的next存儲的是NULL。如此以來,如果一個節點的next是空了,則說明這個節點一定是最後一個節點,這就是鏈表的原理

如果我還需要存儲數據,給火車後面加車廂就可以了。所以鏈表的優點在於它是真正的動態數據結構,不需要像靜態數組一樣處理固定容量的問題

對於鏈表,需要存儲多少個數據,就生成多少個節點把它們掛接起來,但同時,鏈表也喪失了隨機訪問的能力,不能像數組一樣用索引取值。這是因爲從底層機制上數組開闢的空間在內存裏是連續分佈的,可以直接用O(1)的操作拿出數據;鏈表由於是靠next一層一層連接,在計算機的底層每一個節點它所在的內存的位置是不同的,必須依靠next來找到元素,這也是鏈表最大的缺點

數組與鏈表簡單對比

  • 數組最好用於索引有語意的情況,鏈表則不適合有語意。
  • 數組最大優點支持快速查詢,而鏈表最大優點是動態。

鏈表節點的簡單結構

將節點設計成一個私有的內部類,對用戶屏蔽
LinkedList.java

// 支持泛型
public class LinkedList<E> {
    // 節點設計成鏈表類中的內部類
    // 設計私有類,只有在鏈表數據結構內纔可以訪問到Node
    private class Node {
        // 設計成public 在LinkedList中可以隨意訪問操作 不需要設置get,set方法
        public E e;   // 存放元素
        public Node next;  // 指向Node的引用

        public Node(E e, Node next) {
            // 將用戶傳來的數據交給節點
            this.e = e;
            this.next = next;
        }

        // 用戶只傳來e
        public Node(E e) {
            this(e, null);
        }

        // 用戶什麼都不傳
        public Node() {
            this(null, null);
        }

        // 對每一個節點設置toString方法
        @Override
        public String toString() {
            // 每一個節點,直接打印e所對應的toString
            return e.toString();
        }
    }
}


寫在最後

如果代碼有還沒有看懂的或者我寫錯的地方,歡迎評論,我們一起學習討論,共同進步。
推薦學習地址:
liuyubobobo老師的《玩轉數據結構》:https://coding.imooc.com/class/207.html
最後,祝自己早日鹹魚翻身,拿到心儀的Offer,衝呀!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章