數據結構——線性結構(鏈表)


  鏈表定義:鏈表是由一系列節點組成的元素結合。每個節點包含兩個部分,數據域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的列表在一開始申請的空間不足時,也是通過重新申請新的空間,將原來內存空間的內容拷貝進去。

    可以嘗試利用鏈表重新實現棧和隊列,使用棧實現隊列就不用考慮隊滿的問題,也不用設計為環形。

  鏈表這種鏈式存儲的數據結構對樹和圖的結構有很大的啟發性。

 

 

 

 

 

  

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM