資料結構-連結串列結構分析(LinkedList)。
轉載請註明作者:Edison丶夢楠
如有錯誤之處,還請您務必在留言區留下您的寶貴經驗。或傳送郵箱:[email protected] 告知。
本人非常感謝!希望能和您共同學習,共同進步!
下面介紹連結串列的兩種結構:
單向連結串列:只能從頭遍歷到尾,或者從尾遍歷到頭。
圖例:
next:獲取下一個節點。
ele:每個節點中的元素。
first:指頭部,連結串列中第一個元素。
我們可以理解為,當拿到連結串列物件,呼叫first()就可以得到第一個元素。
size:指元素的個數。(或連結串列的長度-1,索引從0開始),在集合中沒有length一說。陣列中的length相當於集合框架中的size
模擬程式碼為:
//單向連結串列
class Node{
Node next: //下一個節點 宣告方法
Object ele: //節點中的資料 宣告方法
public static void main(String [] Nodetest){
Node cnode = new Node();
cnode.next(); //獲取下一個元素
cnode.ele(); //獲取當前節點元素。
cnode.next().ele(); //獲取下一個節點中的元素
}
}
雙向連結串列:可以從頭遍歷到尾,也可以從尾遍歷到頭。
我們可以理解為,雙向連結串列其實就是兩個單向連結串列的合成。只不過是一個從頭到尾,一個從尾到頭。
圖例:
prev:表示上一個節點
Node first:拿到第一個節點
Node last:拿到最後一個節點。
模擬程式碼:
//模擬雙向連結串列程式碼 class Node{ Node first: //第一個節點 宣告方法 Node last: //最後一個節點 宣告方法 Node prev: //上一個節點 Node next: //下一個節點 宣告方法 Object ele: //節點中的資料 宣告方法 public static void main(String [] Nodetest){ Node cnode = new Node(); cnode.next(); //獲取下一個節點 cnode.ele(); //獲取當前節點元素。 cnode.next().ele(); //獲取下一個節點中的元素 cnode.first(); //獲取第一個節點 cnode.last(); //獲取最後一個節點 cnode.prev(); //獲取上一個節點 } }
基於連結串列的實現程式碼:
//基於雙向連結串列的集合
/**
*具體操作程式碼請參見LinkedList原始碼
*這裡不作具體實現
*/
pub11c class MyLinkedL1st {
private Node first;//連結串列的第一個節點
private Hode last;//連結串列的最後一個節點
private int s1ze;//節點的數量
//連結串列中的每一個節點
class Node {
Node prev;//上一個節點物件
Node Next;//下一個節點物件
Object ele;//當前節點中儲存的元素
}
}
總結:對於連結串列操作,無疑是雙向連結串列功能更強大。而雙向連結串列在取頭和尾的時候速度更快。
對於連結串列LinkedList的具體實現,我們仔細讀原始碼可以得出:
在刪除操作上,連結串列結構相對於陣列結構要更快。
為什麼呢?
陣列每次進行刪除操作都要進行移位與遍歷。當某個元素被刪除時,後面的元素要向前補位。最後一個元素設為null,
然後再刪除最後一個元素所佔的記憶體空間。
連結串列的刪除操作演算法分析:
刪除(first也可當做current)即第一個節點時,把下一個節點的next賦給第一個節點的next。把第一個節點的prev設為null;
刪除最後一個節點時,把最後一個節點的prev賦給當前物件的last,再把current節點的上一個(prev)節點的next設為null;
刪除中間(此處中間節點指將要被刪除的節點current)節點時,把current節點的next賦給current節點的上一個節點的next。
再把current節點的prev賦給current節點的下一個節點的prev。
下面給出具體實現程式碼:
前文說過,LinkedList在向頭和尾新增元素時,效能更優。下面給出具體實現程式碼及程式碼分析:
在向頭部新增元素時演算法實現:
把新增之前第一個節點設為新增節點的next節點,然後把新增節點作為之前第一個節點的上一個節點。(或換種說法:把之前第一個節點的上一個節點作為新增節點),再把新增節點作為第一個節點。而新增節點的prev最好設定為null
向尾部新增元素演算法實現:
把新增節點作為之前最後一個節點的next節點,再把之前最後一個節點作為新增節點的上一個節點。
再把物件的last屬性設定為新增節點即可。
對LinekdList操作的效能分析:
1):增操作:
雙向連結串列可以直接獲取自己的第一個和最後一一個節點,
如果新增的元素在第一個或最後一 個位置,那麼操作只有1次.
2):刪除操作(removeFisrt,removelast):
如果刪除第一個元素:操作一一次.如果操作最後一個元素:操作一次如果刪除中間的元素:
找到元素節點平均操作:(1+N)/2次.找到節點之後做刪除操作: 1次.3):查詢操作:
平均:(N+1y2次4):修改操作:
平均:(N+1)/2次
基於前文(ArrayList效能分析),我們可以得出ArrayList和LinkedList的各自優異之處。基於陣列的列表和基於連結串列的列表的效能對比: Arraylist:查詢,更改較快,新增和刪除較慢 Linkeduist查詢更改較慢,新增和刪除較快