1. 程式人生 > >雙向連結串列與迴圈連結串列

雙向連結串列與迴圈連結串列

雙向連結串列

單鏈表的一個優點是結構簡單,但是它也有一個缺點,即在單鏈表中只能通過一個結點的引用訪問其後續結點,而無法直接訪問其前驅結點,
要在單鏈表中找到某個結點的前驅結點,必須從連結串列的首結點出發依次向後尋找,但是需要Ο(n)時間。
為此我們可以擴充套件單鏈表的結點結構,使得通過一個結點的引用,不但能夠訪問其後續結點,也可以方便的訪問其前驅結點。
擴充套件單鏈表結點結構的方法是,在單鏈表結點結構中新增加一個域,該域用於指向結點的直接前驅結點。
擴充套件後的結點結構是構成雙向連結串列的結點結構,如圖 所示。

雙向連結串列是通過上述定義的結點使用 pre 以及 next 域依次串聯在一起而形成的。一個雙向連結串列的結構如圖所示。
 


在雙向連結串列中同樣需要完成資料元素的查詢、插入、刪除等操作。在雙向連結串列中進行查詢與在單鏈表中類似,只不過在雙向連結串列中查詢操作可以從連結串列的首結點開始,
也可以從尾結點開始,但是需要的時間和在單鏈表中一樣

在使用雙向連結串列實現連結表時,為使程式設計更加簡潔,我們使用帶兩個啞元結點的雙向連結串列來實現連結表。
其中一個是頭結點,另一個是尾結點,它們都不存放資料元素,
頭結點的pre 為空,而尾結點的 Next 為空

        
在具有頭尾結點的雙向連結串列中插入和刪除結點,無論插入和刪除的結點位置在何處,因為首尾結點的存在,插入、刪除操作都可以被歸結為某個中間結點的插入和刪除;
並且因為首尾結點的存在,整個連結串列永遠不會為空,因此在插入和刪除結點之後,
也不用考慮連結串列由空變為非空或由非空變為空的情況下 head 和 tail 的指向問題;從而簡化了程式。    

Java中的LinkedList底層使用的就是雙向連結串列。

迴圈連結串列
    在一個迴圈連結串列中, 首節點和末節點被連線在一起。這種方式在單向和雙向連結串列中皆可實現。
    要轉換一個迴圈連結串列,你開始於任意一個節點然後沿著列表的任一方向直到返回開始的節點。
    迴圈連結串列可以被視為"無頭無尾"。

迴圈連結串列中第一個節點之前就是最後一個節點,反之亦然。
迴圈連結串列的無邊界使得在這樣的連結串列上設計演算法會比普通連結串列更加容易。
對於新加入的節點應該是在第一個節點之前還是最後一個節點之後可以根據實際要求靈活處理,區別不大。

    另外有一種模擬的迴圈連結串列,就是在訪問到最後一個節點之後的時候,手工跳轉到第一個節點。
    訪問到第一個節點之前的時候也一樣。這樣也可以實現迴圈連結串列的功能,在直接用迴圈連結串列比較麻煩或者可能會出現問題的時候可以用。
    
    單向連結串列的迴圈帶頭結點的非空連結串列

     
    單向連結串列的迴圈帶頭結點的空連結串列
     
      
    
    雙向連結串列的迴圈帶頭結點的非空連結串列


     
    雙向連結串列的迴圈帶頭結點的空連結串列