1. 程式人生 > >《資料結構與演算法》之連結串列—雙端連結串列

《資料結構與演算法》之連結串列—雙端連結串列

2、雙端連結串列

雙端連結串列就是在單鏈表的基礎上增加一個尾節點,使連結串列既有頭節點又有尾節點,這樣方便進行連結串列尾的訪問和刪除。其計算複雜度如下:1、在表頭插入一個新的節點,時間複雜度O(1) ;2、在表尾插入一個新的節點,時間複雜度O(1) ;3、刪除表頭的節點,時間複雜度O(1) ;4、刪除表尾的節點,由於只儲存了表尾的節點,而沒有儲存表尾的前一個節點(單向,只能從前往後推),所以在刪除表尾節點時需要遍歷以找到表尾節點的前一個節點,需查詢N-1次,也就是O(N)。

其實現程式碼如下:

public class DoublePointLinkedList {
	private Node head;// 頭節點
	private Node tail;// 尾節點
	private int size; // 節點的個數

	private class Node {
		private Object data;
		private Node next;

		public Node(Object data) {
			this.data = data;
		}
	}

	public DoublePointLinkedList() {
		size = 0;
		head = null;
		tail = null;
	}

	// 連結串列頭新增節點
	public void addHead(Object data) {
		Node node = new Node(data);
		if (size == 0) { // 如果連結串列為空,那麼頭節點和尾節點都是該新增節點,節點個數加1
			head = node;
			tail = node;
			size++;
		} else { // 如果連結串列不為空,那麼原有頭節點成為下一個節點,新節點成為頭節點,尾節點不變,節點個數加1
			node.next = head;
			head = node;
			size++;
		}
	}

	// 連結串列尾新增節點
	public void addTail(Object data) {
		Node node = new Node(data);
		if (size == 0) {// 如果連結串列為空,那麼頭節點和尾節點都是該新增節點,節點個數加1
			head = node;
			tail = node;
			size++;
		} else { // 如果連結串列不為空,那麼新節點成為下一個節點,新節點成為尾節點,節點個數加1
			tail.next = node;
			tail = node;
			size++;
		}
	}

	// 刪除頭部節點,成功返回true,失敗返回false
	public boolean deleteHead() {
		if (size == 0) {// 當前連結串列節點數為0
			return false;
		}
		if (head.next == null) {// 當前連結串列節點數為1
			head = null;
			tail = null;
			size--;
			return true;
		} else { // 當前節點數大於1,頭節點稱為頭節點的下一個節點
			head = head.next;
			size--;
			return true;
		}

	}

	// 判斷是否為空
	public boolean isEmpty() {
		return (size == 0);
	}

	// 獲得連結串列的節點個數
	public int getSize() {
		return size;
	}
	
	public Object getHead(){
		return head.data;
	}
	
	public Object getTail(){
		return tail.data;
	}

	// 顯示節點資訊
	public void display() {
		if (size > 0) {
			Node node = head;
			int tempSize = size;
			if (tempSize == 1) {// 當前連結串列只有一個節點
				System.out.println("[" + node.data + "]");
				return;
			}
			while (tempSize > 0) {
				if (node.equals(head)) {
					System.out.print("[" + node.data + "->");
				} else if (node.next == null) {
					System.out.print(node.data + "]");
				} else {
					System.out.print(node.data + "->");
				}
				node = node.next;
				tempSize--;
			}
			System.out.println();
		} else {// 如果連結串列一個節點都沒有,直接列印[]
			System.out.println("[]");
		}
	}

}

測試程式碼如下:

private static void DoublePointLinkedListTest() {
		DoublePointLinkedList list=new DoublePointLinkedList();
		System.out.println(list.getSize());
		list.addHead("123");
		System.out.println(list.getSize());
		list.display();
		list.addTail("456");
		list.display();
		System.out.println(list.getHead());
		System.out.println(list.getTail());
		list.addHead("789");
		list.display();
	}