1. 程式人生 > >【資料結構與演算法01】- 陣列、連結串列對比及應用

【資料結構與演算法01】- 陣列、連結串列對比及應用

1. 陣列和連結串列的區別

  • 1.1 底層儲存結構
    • 陣列需要一塊連續的記憶體空間進行儲存
    • 連結串列通過“指標”將一組零散的記憶體塊串聯起來使用
  • 1.2 效能
    • 連結串列和陣列的(增刪查)時間複雜度正好相反
    • 陣列使用連續的記憶體空間,可以藉助快取機制提高效率;連結串列不連續,所以無法藉助快取機制
    • 陣列大小固定,當需要申請更大的空間,需要拷貝資料,很耗時;而連結串列純天然的支援動態擴容
    • 相對來說,連結串列比較耗記憶體,因為需要記錄節點指標,記憶體消耗翻倍

【注】和陣列相比,連結串列更適合插入、刪除操作頻繁的場景,查詢的時間複雜度較高。不過,在具體的軟體開發中,要對陣列和連結串列的各種效能進行對比,綜合考慮再決定使用兩者中的哪一個。

2. 基於單鏈表的LRU快取

2.1 什麼是快取?

快取是一種提高資料讀取性效能的技術,在硬體設計、軟體開發中都有著廣泛的應用,比如常見的CPU快取、資料庫快取、瀏覽器快取等。

2.2 快取淘汰策略有哪些?

Q:快取的特點是什麼? A:快取的大小是有限的,當快取被用滿時,哪些資料應該被清理出去,哪些資料應該被保留下來。這時就需要用到快取淘汰策略。

常見的3種快取淘汰策略:先進先出策略(FIFO,First In, First Out),最少使用策略(LFU,Least Frequently Used),最近最少使用策略(LRU,Least Recently Used)

2.3 單鏈表實現LRU快取淘汰策略

當訪問的資料沒有儲存在快取的連結串列中時,直接將資料插入連結串列表頭,時間複雜度為O(1); 當訪問的資料存在於儲存的快取的連結串列中,將該資料對應的節點,移動到連結串列表頭,時間複雜度為O(n); 如果快取被佔滿,則從連結串列尾部的資料開始清理,時間複雜度為O(1)。

3. 判斷單鏈表是否為迴文連結串列

3.1 定位連結串列中間節點

Q:在不知道連結串列長度或者節點個數的情況,如何定位連結串列中間節點呢? A:我們可以通過快慢指標進行定位。慢指標每次前進一步,快指標每次前進兩步。

	private <T> Node<T> shootingMiddleNode(Node<
T>
node) { if (node == null || node.next == null) { return node; } Node<T> slow = node; Node<T> fast = node; while (slow != null && fast.next != null && fast.next.next != null) { slow = slow.next; fast = fast.next.next; } return slow; }
3.2 從中間節點下一個節點開始進行翻轉連結串列
	private <T> Node<T> reverseList(Node<T> root) {
		Node<T> pre = null;
		Node<T> next = null;
		while (root != null) {
			next = root.next;
			root.next = pre;
			pre = root;
			root = next;
		}
		return pre;
	}
3.3 比對是否為迴文
	public <T> boolean isPalindrome(Node<T> root) {
		if (root == null || root.next == null) {
			return true;
		}
		Node<T> middleNode = shootingMiddleNode(root);
		middleNode.next = reverseList(middleNode.next);
		
		Node<T> first = root;
		Node<T> second = middleNode.next;
		while (first != null && second != null && Objects.equals(first.data, second.data)) {
			first = first.next;
			second = second.next;
		}
		return second == null;
	}

完整程式碼實現可以點選這裡檢視 當然,這裡通過雙向連結串列進行實現會簡單很多,畢竟存在前驅和後繼指標。

【注】除了單鏈表外,還有演化出來的雙向連結串列,迴圈單鏈表,迴圈雙向連結串列。