資料結構與演算法(五)-線性表之雙向連結串列與雙向迴圈連結串列
阿新 • • 發佈:2018-12-11
前言:前面介紹了迴圈連結串列,雖然迴圈連結串列可以解決單鏈表每次遍歷只能從頭結點開始,但是對於查詢某一節點的上一節點,還是頗為複雜繁瑣,所以可以在結點中加入前一個節點的引用,即雙向連結串列
一、簡介
雙向連結串列:在連結串列中,每一個節點都有對上一個節點和下一個節點的引用或指標,即從一個節點出發可以有兩條路可選擇。 雙向連結串列也叫雙鏈表,是連結串列的一種,它的每個資料結點中都有兩個指標或引用,分別指向直接後繼和直接前驅。所以,從雙向連結串列中的任意一個結點開始,都可以很方便地訪問它的前驅結點和後繼結點。一般我們都構造雙向迴圈連結串列。 特性:- 遍歷可逆性:可以反向遍歷;
- 相比於單鏈表,迴圈單鏈表無論是插入還是遍歷,更便利,更快捷;
- 雙向連結串列可以有效的提高演算法的時間效能,說白了就是用空間換時間;
二、雙向連結串列實現
1、建立節點類Node,其中有三個屬性pre、object、next,pre為上一個節點的引用,也叫作前驅節點,object儲存資料,next為下一個節點的引用,也叫作後繼節點:public class BothwayLoopChain<T> { //頭結點直接引用 private Node<T> head; //鏈長度 private Integer size;BothwayLoopChain.java 2、獲取位置的結點://初始化 BothwayLoopChain() { head = new Node<T>(); head.setNext(null); size = 0; } class Node<T> { private Node<T> pre; private Object object; private Node<T> next; public Node<T> getPre() {return pre; } public void setPre(Node<T> pre) { this.pre = pre; } public Object getObject() { return object; } public void setObject(Object object) { this.object = object; } public Node<T> getNext() { return next; } public void setNext(Node<T> next) { this.next = next; } } }
public T get(Integer index) throws Exception { return (T) getNode(index).getObject(); } private Node<T> getNode(Integer index) throws Exception { if (index > size || index < 0) { throw new Exception("index outof length"); } Node<T> p = head; for (int i = 0; i < index; i++) { p = p.next; } return p; }3、插入節點:
//在尾節點後插入節點 public void add(T t) throws Exception { this.add(t,size); } //在index位置後插入一個節點 public void add(T t, Integer index) throws Exception { //建立新節點 Node<T> p = new Node<>(); p.setObject(t); //獲取該位置的節點 Node<T> s = getNode(index); p.setPre(s); if (s.getNext() != null) { //將本節點的next節點放入新節點的next節點 p.setNext(s.getNext()); s.getNext().setPre(p); } else { p.setNext(null); } size++; }4、移除節點:
//移除節點並返回 public Node<T> remove(Integer index) throws Exception { //獲取該位置的節點 Node<T> s = getNode(index); //獲取該位置節點的下一個節點 Node<T> next = s.getNext(); //將本節點的pre節點的next節點設定為next s.getPre().setNext(next); next.setPre(s.getPre()); return s; }至此,雙向連結串列的基本實現已完成,其實它就是用空間換時間來提高效能的; 之前瞭解了單鏈表的迴圈結構即單向迴圈連結串列,舉一反三,雙向連結串列也有迴圈結構,即雙向迴圈連結串列;
三、雙向連結串列擴充套件—雙向迴圈連結串列
在雙向連結串列的基礎上進行改造:- 尾節點的next指向頭結點;
- 頭結點的pre指向尾節點;
//在index位置後插入一個節點 public void add(T t, Integer index) throws Exception { //建立新節點 Node<T> p = new Node<>(); p.setObject(t); //獲取該位置的節點 Node<T> s = getNode(index); p.setPre(s); //將本節點的next節點放入新節點的next節點 p.setNext(s.getNext()); s.getNext().setPre(p); size++; }
本系列參考書籍:
《寫給大家看的演算法書》
《圖靈程式設計叢書 演算法 第4版》