一、概述
鏈表是一種插入和刪除都比較快的數據結構,缺點是查找比較慢。除非需要頻繁的通過下標來隨機訪問數據,否則在很多使用數組的地方都可以用鏈表代替
在鏈表中,每個數據項都包含在“鏈結點”中,一個鏈結點是某個類的對象。每個鏈結點對象中都包含一個對下一個鏈接點的引用,鏈表本身的對象中有一個字段指向第一個鏈結點的引用,如下圖所示:
在數組中,每一項占用一個特定的位置,這個位置可以用一個下標號直接訪問,就像一排房子,你可以憑房間號找到其中特定的意見。在鏈表中,尋找一個特定元素的唯一方法就是沿着這個元素的鏈一直找下去,知道發現要找的那個數據項
1.1、單鏈表
上述介紹其實就是基本的單鏈表
上面展示的是一個單鏈表的存儲原理圖,head為頭節點,不存放任何的數據,只是充當一個指向鏈表中真正存放數據的第一個節點的作用,而每個節點中都有一個next引用,指向下一個節點,就這樣一節一節往下面記錄,直到最后一個節點,其中的next指向null。
1.1.1、節點刪除
鏈表的刪除指定鏈結點,是通過將目標鏈結點的上一個鏈結點的next指針指向目標鏈結點的下一個鏈結點,示意圖如下:
通過這種方法,在鏈表的指針鏈中將跳過與刪除的元素,達到刪除的目的。不過,實際上刪除掉的元素的next指針還是指向原來的下一個元素的,只是它不能再被單鏈表檢索到而已,JVM的垃圾回收機制會在一定的時間之后回收它
1.1.2、節點添加
添加鏈結點比刪除復雜一點,首先我們要使插入位置之前的鏈結點的next指針指向目標鏈結點,其次還要將目標鏈結點的next指針指向插入位置之后的鏈結點。本例中的插入位置僅限於鏈表的第一個位置,示意圖如下:
代碼實現:data-003-link Link
其中node是基本節點,Link是單鏈表實現。
1.2、 雙端鏈表
雙端鏈表與雙向鏈表是完全不同的兩個概念
雙端鏈表與單鏈表的區別在於它不只第一個鏈結點有引用,還對最后一個鏈結點有引用,如下圖所示:
由於有着對最后一個鏈結點的直接引用.所以雙端鏈表比傳統鏈表在某些方面要方便.比如在尾部插入一個鏈結點.雙端鏈表可以進行直接操作
但傳統鏈表只能通過next節點循環找到最后鏈結點操作.所以雙端鏈表適合制造隊列.
雙端鏈表可以插入表尾,但是仍然不能方便的刪除表尾,因為我們沒有方法快捷地獲取倒數第二個鏈結點,雙端鏈表沒有逆向的指針,這一點就要靠雙向鏈表來解決了
代碼實現:data-003-link DoubleEndLink
1.3、雙向鏈表
傳統鏈表存在着一個潛在的問題,就是沒有反向引用,由上一個鏈結點跳到下一個鏈結點很容易,而從下一個鏈結點跳到上一個鏈結點很困難
雙向鏈表提供了這種能力,即允許向前遍歷,也允許向后遍歷。實現這種特性的關鍵在於每個鏈結點既有下一個鏈結點的引用,也有上一個鏈結點的引用,如下圖所示:
1.3.1、插入操作
雙向鏈表的插入和刪除會變得更復雜,因為同時要處理雙倍的指針變化。
1》頭部之后第一節點插入
尾部類似。
2》其他位置插入
1.3.2、刪除
需要定位到要刪除的鏈結點,然后改變了其前后鏈結點的指針,示意圖如下:
代碼實現:data-003-link DoubleLink
主要麻煩的是插入刪除,指針的指向。