1. 程式人生 > >線性表——雙向連結串列

線性表——雙向連結串列

雙向連結串列簡介

雙向連結串列是一種特殊的連結串列。

在單向連結串列中我們要查詢下一個結點非常的方便,但是要查詢上一個節點就困難了,雙向連結串列克服了單鏈表的單向性這個缺點,

單鏈表和雙向連結串列的區別

單鏈表:只能向一個方向遍歷

雙向連結串列:向兩邊都可以遍歷。

雙向連結串列的實現

為了找到節點和前驅,我們給節點增加一個指向其前驅的指標,如下圖所示

既然單鏈表可以迴圈,那麼雙向連結串列也就可以迴圈,如下圖所示即為雙向迴圈連結串列

雙向連結串列的基本操作

1.建立雙向連結串列

建立雙向連結串列和建立單鏈表大同小異,雙向連結串列的結點有三個域,資料域、前驅和後繼。

當連結串列為空時,頭結點的前驅和後繼都指向它自己,自己構成一個環。

當連結串列不為空時,除尾結點外,每個結點的前驅都指向它的前一個結點,後繼均指向它的後一個結點,尾節點的後繼指向頭結點。

2.增加元素

把元素增加在連結串列最後。

① 建立一個新的節點

② 新結點的後繼為頭結點

③ 新結點的前驅為尾節點

④ 尾節點的後繼為新結點

⑤ 頭結點的前驅為新結點

⑥ 將尾指標移動到新結點上

把元素插在連結串列任意位置,如下圖所示

① 建立新結點

② 遍歷連結串列到達指定的位置 p

③ 新結點的後繼等於 p 的後繼

④ 新結點的後繼(P的後繼)的前驅等於新結點

⑤ 新結點的前驅等於 p 

⑥ p 的後繼等於新結點

3.刪除元素

刪除尾結點

① 尾節點的前驅的後繼等於頭結點

② 頭結點的前驅等於尾節點的前驅

③ 尾指標向前移動一下

刪除任意位置的元素

① 遍歷連結串列到適當的位置 p (待刪除的節點)

② p 的前驅的後繼等於  p 的後繼

③ p 的後繼的前驅等於 p 的前驅

/**
 * 結點類
 */
class Node2<T>{
	/**
	 * 資料域
	 */
	T data ;
	/**
	 * 前驅
	 */
	Node2<T> pre ;
	/**
	 * 後繼
	 */
	Node2<T> next ;
	
	public Node2(){
		this.data = null;
		this.pre = null;
		this.next = null;
	}
	
	public Node2(T data){
		this.data = data;
		this.pre = null;
		this.next = null;
	}
}

/**
 * 連結串列 
 */
class doubleCycle<T>{
	/**
	 * 頭結點
	 */
	Node2<T> head;
	/**
	 * 尾指標
	 */
	Node2<T> last;
	/**
	 * 雙向迴圈連結串列的長度
	 */
	int size;
	
	public doubleCycle(){
		head = new Node2<T>();
		last = head;
		head.next = head;
		head.pre = head;
		size = 0;
	}
	
	/**
	 * 增加一個元素
	 * @param data
	 */
	public void add(T data){
		Node2<T> node = new Node2<T>(data);
			last.next = node;
			node.pre = last;
			node.next = head;
			head.pre = node;
			last = node;
			size++;
	}
	
	/**
	 * 刪除一個元素
	 * @param data
	 * @return
	 */
	public boolean delete(T data){
		Node2<T> p = head.next;
		while(p != head){
			if(p.data == data){
				if(p == last){//如果是最後一個元素被刪除,則要移動尾指標。
					last = p.pre;
				}
				p.next.pre = p.pre;
				p.pre.next = p.next;
				size--;
				return true;
			}
			p = p.next;
		} 
		return false;
	}
	
	
	public void show(){
		Node2<T> p = head.next;
		while(p != head){
			System.out.print(p.data+" ");
			p = p.next;
		}
		System.out.println();
	}
	public void show2(){
		Node2<T> p = last;
		while(p != head){
			System.out.print(p.data+" ");
			p = p.pre;
		}
		System.out.println();
	}
}

public class demo5 {
	public static void main(String[] args){
		doubleCycle<Integer> link = new doubleCycle<Integer>();
		link.add(84);	link.add(45);	link.add(75);
		link.add(15);	link.add(11);	link.add(23);
		link.add(29);	link.add(7);	
		
		link.show();	link.show2();  link.delete(45);
		System.out.println("刪除45");
		
		link.show();	link.show2();	link.delete(11);
		System.out.println("刪除11");
		
		link.show();	link.show2();	link.delete(7);
		System.out.println("刪除7");
		
		link.show();	link.show2();	
	}
}

執行結果

84 45 75 15 11 23 29 7 
7 29 23 11 15 75 45 84 
刪除45
84 75 15 11 23 29 7 
7 29 23 11 15 75 84 
刪除11
84 75 15 23 29 7 
7 29 23 15 75 84 
刪除7
84 75 15 23 29 
29 23 15 75 84