在瞭解雙向循環鏈表以前,若是對鏈表尚未一個清晰的概念,建議你看看單鏈表和單向循環鏈表,這有利於你更好的理解下面的內容。(廢話有點多[逃]html
相比單鏈表,雙向循環鏈表是一個更加複雜的結構。由於雙向循環鏈表的節點不只包含指向下一個節點的指針(next),還包含指向前一個節點的指針(prev)。java
雙向循環鏈表的基本操做有:增(add),刪(remove),改(set),查(find),插(insert)等。在這裏咱們只講解remove,insert和getNode操做,其餘實現可看下方源碼。node
因爲雙向鏈表有兩個可見的節點(head和end),所以雙向循環鏈表獲取節點的操做和單鏈表有所不一樣。算法
雙鏈表的設計應用了算法設計的「空間換時間」思想,經過消耗更多的空間來縮小操做的時間複雜度。this
public class Node<Anytype> { public Anytype data;//數據 public Node<Anytype> prev;//前一個節點 public Node<Anytype> next;//後一個節點 public Node(Anytype data,Node<Anytype> prev,Node<Anytype> next){ this.data=data; this.prev=prev; this.next=next; } } ---------------------------------------------- public class DoubleLink<AnyType> { Node<AnyType> head;//頭指針 Node<AnyType> end;//尾節點 int size;//記錄鏈表長度 //初始化鏈表 public void initlist(){ end=new Node<>(null,null,null); head=new Node<>(null,null,end); end.prev=head; end.next=head; size=0; } //獲取長度 public int length(){ return size; } //獲取節點 public Node<AnyType> getNode(int index){ Node<AnyType> n; if(index>=size/2){ n=end; for(int i=length();i>index;i--){ n=n.prev; } return n; } else{ n=head; for(int i=0;i<=index;i++){ n=n.next; } return n; } } //添加元素 public void add(AnyType a){ Node<AnyType> renode=new Node<>(a,getNode(size-1),end); renode.prev.next=renode; renode.next.prev=renode; size++; } //插入元素 public void insert(int i,AnyType a){ Node<AnyType> n=getNode(i); Node<AnyType> renode=new Node<>(a,n.prev,n); n.prev.next=renode; n.prev=renode; size++; } //刪除元素 public AnyType remove(int i){ Node<AnyType> n=getNode(i); AnyType data=n.data; n.prev.next=n.next; n.next.prev=n.prev; size--; return data; } //獲取i位置的數據 public AnyType get(int i){ return getNode(i).data; } //爲i位置元素從新賦值 public AnyType set(int i,AnyType a){ Node<AnyType> n=getNode(i); AnyType old=n.data; n.data=a; return old; } //清空鏈表 public void clear(){ initlist(); } public void print(){ for(int i=0;i<size;i++){ System.out.println(getNode(i).data); } } }