鏈表定義:鏈表是由一系列節點組成的元素結合。每個節點包含兩個部分,數據域item和指向下一個節點的指針next。通過節點之間的相互連接,最終串聯成一個鏈表。
一、單鏈表
1、節點定義
class Node: def __init__(self, item): self.item = item self.next = None # 模擬鏈表 a = Node(1) b = Node(2) c = Node(3) a.next = b b.next = c print(a.next.next.item) # 輸出:3
2、建立鏈表
(1)頭插法
頭插法是在頭結點這邊插入。
(2)尾插法
不光要知道頭還需要知道尾在哪。從尾節點插入。
(3)代碼實現
class Node: def __init__(self, item): self.item = item # 存放數據 self.next = None # 指針,指向下一個節點 def create_linklist_head(li): """頭插法創建鏈表""" head = Node(li[0]) # 頭節點 for element in li[1:]: # 從第二個到最后一個遍歷列表 node = Node(element) # 實例化為一個鏈表節點 node.next = head # 設置實例的next屬性指向鏈表頭節點 head = node # 將新加入鏈表節點設置為頭節點 return head # 要遍歷鏈表需要從頭往回找 def create_linklist_tail(li): """尾插法創建鏈表""" head = Node(li[0]) # 創建頭節點對象 tail = head # 尾節點也是頭節點 for element in li[1:]: # 從第二個到最后一個遍歷列表 node = Node(element) # 創建一個新鏈表節點 tail.next = node # 設置實例next屬性指向鏈表尾節點 tail = node # 將新加入鏈表的節點設置為尾節點 return head # 返回頭節點,可以從頭往回找 def print_linklist(lk): """打印鏈表""" while lk: # 只要lk存在 print(lk.item, end=',') # 打印鏈表值 lk = lk.next # 到最后一個節點的時候,lk.next屬性為空退出循環 lk = create_linklist_head([1, 2, 3]) print(lk) print_linklist(lk) """ <__main__.Node object at 0x10402de48> 3,2,1, """ lk2 = create_linklist_tail([1, 3, 6, 8, 9]) print_linklist(lk2) """ 3,2,1,1,3,6,8,9, """
3、鏈表的遍歷
4、鏈表節點的插入和刪除(視頻缺,需要補)
二、雙鏈表
雙鏈表的每個節點有兩個指針:一個指向后一個節點,另一個指向前一個節點。
1、節點定義
class Node(object): def __init__(self, item): self.item = item # 數據 self.next = None # 指針,指向后一個節點 self.prior = None # 指針,指向前一個節點
2、雙鏈表節點插入
#插入 p.next = curNode.next curNode.next.prior = p p.prior = curNode curNode.next = p
代碼過程圖示如下:
(1)p.next = curNode.next 讓p.next指針指向curNode下一個節點
(2)curNode.next.prior = p 讓curNode下一個節點的prior指針指向p
(3)p.prior = curNode 讓p的prior指針指向curNode
(4)curNode.next = p 讓curNode的next指針指向p
3、雙鏈表節點的刪除
#刪除 p = curNode.next curNode.next = p.next p.next.prior = curNode del p
代碼過程圖示如下:
(1)p = curNode.next 指定要刪除的節點是curNode的next指針指向的節點
(2)curNode.next = p.next 修改curNode的next指針指向要刪除節點的next指針指向的節點
(3)p.next.prior = curNode 修改p的next指針指向的節點的prior指針,將指針指向curNode
(4)del p 刪除p
三、鏈表總結
1、順序表(列表)與 鏈表復雜度對比分析
按元素值查找時:都是挨個查看,時間復雜度都為O(n)
按下標查找時:順序表更快,直接插入到對位位置。鏈表則需要從頭開始數。鏈表時間復雜度是O(n),順序表時間復雜度是O(1)。
在某元素后插入:這種情況順序表是O(n),插入后,后面的元素都需要往后挪。鏈表則是O(1)。
刪除某元素:這種情況順序表是O(n),刪除后,后面的元素都需要往前挪。鏈表則是O(1)。
2、鏈表和順序表對比總結
鏈表在插入和刪除操作上明顯快於順序表。
鏈表的內存可以更靈活的分配。java等的數組一開始申請的空間如果滿了是沒有辦法解決的,python的列表在一開始申請的空間不足時,也是通過重新申請新的空間,將原來內存空間的內容拷貝進去。
可以嘗試利用鏈表重新實現棧和隊列,使用棧實現隊列就不用考慮隊滿的問題,也不用設計為環形。
鏈表這種鏈式存儲的數據結構對樹和圖的結構有很大的啟發性。