Linked List

Linked List用節點(Node)來保存相同類型data,並用pointor指向下一個node,把node串接起來就是一個Linked List,而通常Linked List的終點是一個null

Linked Lis分為單向鏈表(Singly Linked List)雙向鏈表(Doubly Linked List)環形鏈表(Circular Linked List)三種類型。Singly Linked List中每個節點只有一個指針指向下一個節點。Doubly Linked ListSingly Linked List多一個指針,每個節點既有一個指向下一個節點的指針,也有一個指向前一個節點的指針。Circular Linked List的最後一個節點的指針指向第一個節點,形成一個環。

  • 單向鏈表(Singly Linked List)
  • 雙向鏈表(Doubly Linked List)
  • 環形鏈表(Circular Linked List)

Linked List(鏈表)和 Array(數組)的區別

  • 存儲方式:Array 是一種連續存儲的資料結構,它的元素在內存中是連續存放的,可以通過下標來訪問特定位置的元素;而 Linked List 則是一種不連續存儲的資料結構,每個節點只包含了一個data和指向下一個節點的pointor。
  • 大小可變性:Array 的大小是固定的,一旦創建後,就不能再增加或減少;而 Linked List 的大小是可變的,可以增加或減少節點。
  • 時間複雜度:Array 的訪問、查找和更新的時間複雜度為 O(1);而 Linked List 的訪問和查找的時間複雜度為 O(N),更新的間複雜度為 O(N),而 Linked List 的空間複雜度則為 O(N)。

Array 訪問和更新方面具有優勢,但在插入和刪除方面較為困難。

Linked List插入和刪除方面具有優勢,但在訪問和查找操作方面較為困難。

在什麼情況下需要Linked List ?

根據以上結論,當數據需要頻繁地進行插入或刪除操作時就很適合用Linked List ,只需要修改相鄰節點的指針即可。由於Array在內存中分配的空間是固定的,插入或刪除一個元素可能需要移動數組中的其他元素,當數據需要頻繁地進行插入或刪除操作時,需要重新分配和復制數組的整個數據集,所以無法靈活地處理動態數據。

在需要實現搜索和遍歷操作時,Array的線性搜索可能會很慢,而Linked List可以通過使用指針進行快速遍歷。但Linked List 也有一些缺點。由於每個節點需要保存指向下一個節點的指針,因此在內存使用方面可能會比Array更浪費一些空間。此外,Linked List無法隨機訪問節點,因此在需要隨機訪問數據的場景中,用Array會更好。

Linked List 的寫法

Insert

如果想要在0和1中Insert一個2的話

# 創建一個節點,值為0,同時將head和ptr都指向這個節點
ptr = head = Node(0)

# 創建一個newnode,值為1,並將其插入到鏈表中,使得ptr指向1
newnode = Node(1)
ptr.next = newnode
ptr = ptr.next

# 創建一個newnode,值為2,並將其插入到鏈表中,使得head指向2,2的next指向1
newnode = Node(2)
head.next = newnode
new_node.next = ptr       
Delete

如果想要在0和1中I把剛剛創的2刪掉的話

# 先找到2
p = head   # p指向head,p指向0
p = p.next # 將p指向下一個node,即指向2                 0(head) -> 2(p) -> 1(ptr)

# 刪除2
head.next = p.next # 將head指向下一個node,跳過2        0(head) -> 1(ptr)
p.next = None # 將p的下一個node指向空node,即把2移除    
Search

如果想要找到2的話

# 0(head) -> 2 -> 1(ptr)

p = head           
# 定義指針p指向head
while p:           # 循環檢查每個節node的值
	if p.val == 2: # 找到值等於2的node 跳出迴圈
		break
	p = p.next     # 不然就把指針指向下一個