鏈表定義:鏈表是由一系列節點組成的元素結合。每個節點包含兩個部分,數據域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的列表在一開始申請的空間不足時,也是通過重新申請新的空間,將原來內存空間的內容拷貝進去。
可以嘗試利用鏈表重新實現棧和隊列,使用棧實現隊列就不用考慮隊滿的問題,也不用設計為環形。
鏈表這種鏈式存儲的數據結構對樹和圖的結構有很大的啟發性。
