了解 Python 中的链表实现

在程式設計的世界中,資料結構扮演著至關重要的角色。它們幫助我們以有效率的方式組織和管理資料。

在本篇教程中,我們將深入探討單向鏈表和雙向鏈表這兩種基本資料結構。

鏈表是一種線性資料結構,與陣列不同,它不將資料儲存在連續的記憶體位置。鏈表中的每個元素都稱為節點,這些節點透過指標相互連接。鏈表中的第一個節點被稱為頭節點。

鏈表的大小是動態的,這意味著我們可以根據設備的可用記憶體來增加或減少節點的數量。

鏈表主要分為兩種型別。 讓我們逐一深入了解它們的詳細資訊。

#1. 單向鏈表

單向鏈表中的每個節點都包含一個指向鏈表中下一個節點的指標。因此,每個節點都需要儲存資料以及指向下一個節點的指標。

鏈表的最後一個節點的下一個指標會設定為 null,這表示鏈表的結束。

以下是一個鏈表的示意圖:

現在我們對單向鏈表有了基本的理解。 接下來,讓我們看看如何在 Python 中實作它。

單向鏈表的實作

1. 第一步是建立鏈表的節點。

如何建立呢?

在 Python 中,我們可以透過類別輕鬆建立節點。 類別中會包含節點的資料和指向下一個節點的指標。

以下是節點的程式碼:

class Node:

    def __init__(self, data):
        ## 節點的資料
        self.data = data

        ## 下一個節點的指標
        self.next = None

我們可以使用上述類別建立包含任何型別資料的節點。 稍後我們將看到範例。

現在,我們有了節點。 接下來,我們必須建立一個包含多個節點的鏈表。 讓我們為鏈表建立另一個類別。

2. 建立一個名為 LinkedList 的類別,並將頭節點初始化為 None。 請參閱以下程式碼:

class LinkedList:

    def __init__(self):
        ## 將頭節點初始化為 None
        self.head = None

3. 我們有了 Node 和 LinkedList 類別。 我們如何將新的節點插入到鏈表中? 一個簡單的答案是使用 LinkedList 類別中的方法。 是的,這樣做是可行的。 讓我們編寫一個方法來將新的節點插入到鏈表中。

要將新的節點插入到鏈表中,我們必須遵循幾個步驟。

讓我們看看這些步驟:

  • 檢查頭節點是否為空。
  • 如果頭節點為空,則將新節點指定為頭節點。
  • 如果頭節點不為空,則找到鏈表的最後一個節點。
  • 將新節點指定為最後一個節點的下一個指標。

讓我們看看在鏈表中插入新節點的程式碼:

class LinkedList:

    ####

    def insert(self, new_node):
        ## 檢查頭節點是否為空
        if self.head:
            ## 找到最後一個節點
            last_node = self.head
            while last_node.next != None:
                last_node = last_node.next

            ## 將新節點指定給最後一個節點的下一個指標
            last_node.next = new_node

        else:
            ## 頭節點為空
            ## 將節點指定給頭節點
            self.head = new_node

太棒了! 我們已經完成了將新節點插入鏈表的方法。 我們如何存取鏈表中的節點資料?

要存取鏈表中的資料,我們必須像在插入方法中尋找最後一個節點一樣,使用下一個指標來遍歷鏈表。 讓我們在 LinkedList 類別中編寫一個方法,來印出鏈表中所有節點的資料。

4. 依照以下步驟列印出鏈表中所有節點的資料:

  • 使用頭節點初始化一個臨時變數。
  • 編寫一個迴圈,重複直到我們到達鏈表的末端。
    • 印出節點的資料。
    • 移動到下一個指標。

以下是程式碼:

class LinkedList:

    ####

    def display(self):
        ## 用於遍歷的變數
        temp_node = self.head

        ## 重複直到到達鏈表的末端
        while temp_node != None:
            ## 印出節點的資料
            print(temp_node.data, end='->')

            ## 移動到下一個節點
            temp_node = temp_node.next

        print('Null')

呼! 我們已經完成了使用必要方法建立鏈表。 讓我們透過使用一些資料實例化來測試鏈表。

我們可以使用 Node(1) 程式碼來建立節點。 讓我們看看完整的鏈表實作程式碼以及使用範例:

class Node:

    def __init__(self, data):
        ## 節點的資料
        self.data = data

        ## 下一個節點的指標
        self.next = None

class LinkedList:

    def __init__(self):
        ## 將頭節點初始化為 None
        self.head = None

    def insert(self, new_node):
        ## 檢查頭節點是否為空
        if self.head:
            ## 找到最後一個節點
            last_node = self.head
            while last_node.next != None:
                last_node = last_node.next

            ## 將新節點指定給最後一個節點的下一個指標
            last_node.next = new_node

        else:
            ## 頭節點為空
            ## 將節點指定給頭節點
            self.head = new_node

    def display(self):
        ## 用於遍歷的變數
        temp_node = self.head

        ## 重複直到到達鏈表的末端
        while temp_node != None:
            ## 印出節點的資料
            print(temp_node.data, end='->')

            ## 移動到下一個節點
            temp_node = temp_node.next

        print('Null')


if __name__ == '__main__':
    ## 實例化鏈表
    linked_list = LinkedList()

    ## 將資料插入到鏈表中
    linked_list.insert(Node(1))
    linked_list.insert(Node(2))
    linked_list.insert(Node(3))
    linked_list.insert(Node(4))
    linked_list.insert(Node(5))
    linked_list.insert(Node(6))
    linked_list.insert(Node(7))

    ## 印出鏈表
    linked_list.display()

執行上面的程式會得到如下結果:

1->2->3->4->5->6->7->Null

這就是鏈表的運作方式。 現在,您知道如何實作單向鏈表了。 有了單向鏈表的知識,您就可以輕鬆實作雙向鏈表。 讓我們深入本教程的下一部分。

#2. 雙向鏈表

雙向鏈表中的每個節點包含兩個指標:一個指向鏈表中前一個節點,另一個指向下一個節點。 因此,每個節點都需要儲存資料,以及兩個指標。

第一個節點的前一個指標為 null,最後一個節點的下一個指標為 null,這表示鏈表在兩側的結束。

以下是一個鏈表的示意圖:

雙向鏈表的實作步驟與單向鏈表類似。 再次解釋相同的事情對您來說可能會很無聊。 讓我們直接瀏覽程式碼,您會很快理解的。 開始吧!

雙向鏈表的實作

1. 建立一個雙向鏈表的節點,其中包含前一個節點的指標、資料和下一個節點的指標。

class Node:

    def __init__(self, data):
        ## 前一個節點的指標
        self.prev = None

        ## 節點的資料
        self.data = data

        ## 下一個節點的指標
        self.next = None

2. 雙向鏈表類別。

class LinkedList:

    def __init__(self):
        ## 將頭節點初始化為 None
        self.head = None

3. 將新節點插入到雙向鏈表的方法。

class LinkedList:

    ####

    def insert(self, new_node):
        ## 檢查頭節點是否為空
        if self.head:
            ## 找到最後一個節點
            last_node = self.head
            while last_node.next != None:
                last_node = last_node.next

            ## 將最後一個節點指定給新節點的前一個指標
            new_node.prev = last_node

            ## 將新節點指定給最後一個節點的下一個指標
            last_node.next = new_node

4. 雙向鏈表的資料顯示方法。

class LinkedList:

    ####

    def display(self):

        ## 按正常順序印出資料
        print("Normal Order: ", end='')

        temp_node = self.head
        while temp_node != None:
            print(temp_node.data, end=' ')
            temp_node = temp_node.next
        print()

        ## 使用前一個指標按相反順序印出資料
        print("Reverse Order: ", end='')

        ## 找到最後一個節點
        last_node = self.head
        while last_node.next != None:
            last_node = last_node.next

        temp_node = last_node
        while temp_node != None:
            print(temp_node.data, end=' ')
            temp_node = temp_node.prev
        print()

我們已經看到了雙向鏈表的程式碼。 但沒有使用雙向鏈表類別的程式碼。 這留給您來完成。 請使用類似於單向鏈表的方式來實作雙向鏈表類別。 玩得開心! 🙂

結論

您可以根據鏈表找到許多問題。 但是,您必須了解在本教程中學到的鏈表基本實作。 希望您在學習新概念的過程中玩得開心。

快樂編碼!🙂