python資料結構——連結串列(無序列表)

Leosaf發表於2021-01-02

簡單介紹

連結串列是一種無序列表,無序列表只需要維持元素之間的相對位置,但是並不需要在連續的記憶體空間中維護這些位置資訊。
連結串列裡的元素連線時靠每一個元素都維護一份資訊,該資訊就是下一個元素的位置,那麼這些元素的相對位置就能通過指向下一個元素的連結來表示。
在這裡插入圖片描述
但是我們必須要指明連結串列中的第一個元素的位置,一旦知道之後,就可以訪問下一個元素,指向連結串列的第一個元素的引用叫做頭(head)

Node類

節點(node)時構建連結串列的基本資料結構,每一個節點物件都有兩份資訊,資料變數,即該節點的元素,和指向下一個節點的引用。
下面的程式碼我們展示了Node類python的實現,在構建節點時,需要為其提供初始值。Node類也包含了訪問和修改資料的方法。

class Node:
    def __init__(self, initdata):
        self.data = initdata
        self.next = None
    def getData(self):
        return self.data
    def getNext(self):
        return self.next
    def setData(self, newdata):
        self.data = newdata
    def setNext(self, newnext):
        self.next = newnext

UnorderedList類

建立連結串列

如上所述,無序列表(unordered list)是基於節點集合來構建的,每一個節點都通過顯式的引用·來指向下一個節點,只需要知道第一個節點的位置,其後的元素就可以一一找到。因此,它的裡面必須包含指向第一個節點的引用

class UnorderedList:
    def __init__(self):
        self.head = None

開始的時候連結串列為空。在連結串列中,用None來表明沒有元素。

判斷是否為空

下面的程式碼檢查是否為空

    def isEmpty(self):
        return self.head == None

新增元素

要將元素加入連結串列中,需要實現add方法,但是需要知道新的元素要被放在連結串列的哪個位置?由於連結串列是無序的,因此新元素相對於已有元素的位置並不重要,新的元素可以放在任何位置。因此,將新元素放在最簡便的位置是最合理的選擇。
由於連結串列只提供一個入口(頭部),因此其他所有節點都只能通過第一個節點以及next連結來訪問,意味著新增新節點的最簡便的位置就是頭部。
我們把新元素放在連結串列的第一個元素,已有的元素連線到該元素的後面

    def add(self, item):
        temp = Node(item)
        temp.setNext(self.head)
        self.head = temp

我們必須先將新的節點的next引用指向房前連結串列中的第一個節點,才能開始修改頭節點,使其指向新建立的節點。如果順序顛倒,由於頭節點是唯一指向列表節點的外部引用,因此所有的已有節點都將丟失並且無法訪問。

檢查長度

為了實現length方法,我們必須遍歷連結串列並且記錄訪問過多少節點。下列程式碼展示瞭如何遍歷節點。

    def length(self):
        current = self.head
        count = 0
        while current != None:
            count +=1
            current = current.getNext()
        return count

current的作用就是外部引用,他在第二行被初始化為連結串列的頭節點,計算開始時,沒有訪問任何節點,所以count初始化為一。

搜尋方法

在連結串列中實現搜尋也要進行遍歷技術,每訪問一個節點,檢查該節點的元素與要搜尋的是否相同。`

    def search(self, item):
        current= self.head
        found = False
        while current != None and not found:
            if current.getData() == item:
                found = True
            else:
                current = current.getNext

        return found

刪除方法

remove方法在邏輯上分為兩步,第一步遍歷列表並查詢要移除的元素,找到後要將它移除,第二步要修改上一個節點的連結,使它指向下下一個節點。這正是個難點,因此我們在這使用雙指標的方法,我們建立一個新的變數previous使得它總是指向current上一次訪問的節點,這樣一來,就可以進行修改,程式碼如下:

    def remove(self, item):
        current = self.head
        previous = None
        found = False
        while not found:
            if current.getData() == item:
                found = True
            else:
                previous = current
                current = current.getNext()
        if previous == None:
            self.head = current.getNext()
        else:
            previous.setNext(current.getNext())

必須要將previous移動到current的節點然後再移動current,這一過程稱為蠕動。

相關文章