線性數據結構(Python 實現)

一旦一個數據項被添加,它相對於前後元素一直保持該位置不變。諸如此類的數據結構被稱爲線性數據結構。棧,隊列,deques, 列表是一類數據的容器,它們數據項之間的順序由添加或刪除的順序決定。
線性數據結構有兩端,有時被稱爲左右,某些情況被稱爲前後。你也可以稱爲頂部和底部,名字都不重要。將兩個線性數據結構區分開的方法是添加和移除項的方式,特別是添加和移除項的位置。例如一些結構允許從一端添加項,另一些允許從另一端移除項。

棧(有時稱爲“後進先出棧”)是一個項的有序集合,其中添加移除新項總髮生在同一端。這一端通常稱爲“頂部”。與頂部對應的端稱爲“底部”。
棧的底部很重要,因爲在棧中靠近底部的項是存儲時間最長的。最近添加的項是最先會被移除的。這種排序原則有時被稱爲 LIFO,後進先出。它基於在集合內的時間長度做排序。較新的項靠近頂部,較舊的項靠近底部。
棧的例子很常見。幾乎所有的自助餐廳都有一堆托盤或盤子,你從頂部拿一個,就會有一個新的托盤給下一個客人。Figure 1 展示了一個棧,包含了很多 Python 對象。
這裏寫圖片描述
Figure 1

和棧相關的最有用的想法之一來自對它的觀察。假設從一個乾淨的桌面開始,現在把書一本本疊起來,你在構造一個棧。考慮下移除一本書會發生什麼。移除的順序跟剛剛被放置的順序相反。棧之所以重要是因爲它能反轉項的順序。插入跟刪除順序相反,Figure 2 展示了 Python 數據對象創建和刪除的過程,注意觀察他們的順序。
這裏寫圖片描述
Figure 2

想想這種反轉的屬性,你可以想到使用計算機的時候所碰到的例子。例如,每個 web 瀏覽器都有一個返回按鈕。當你瀏覽網頁時,這些網頁被放置在一個棧中(實際是網頁的網址)。你現在查看的網頁在頂部,你第一個查看的網頁在底部。如果按‘返回’按鈕,將按相反的順序瀏覽剛纔的頁面。

棧的抽象數據類型

棧的抽象數據類型由以下結構和操作定義。如上所述,棧被構造爲項的有序集合,其中項被添加和從末端移除的位置稱爲“頂部”。棧是有序的 LIFO 。棧操作如下。

  • Stack() 創建一個空的新棧。 它不需要參數,並返回一個空棧。
  • push(item)將一個新項添加到棧的頂部。它需要 item 做參數並不返回任何內容。
  • pop() 從棧中刪除頂部項。它不需要參數並返回 item 。棧被修改。
  • peek() 從棧返回頂部項,但不會刪除它。不需要參數。 不修改棧。
  • isEmpty() 測試棧是否爲空。不需要參數,並返回布爾值。
  • size() 返回棧中的 item 數量。不需要參數,並返回一個整數。

例如,s 是已經創建的空棧,Table1 展示了棧操作序列的結果。棧中,頂部項列在最右邊。
這裏寫圖片描述
Table 1

Python 代碼實現:

class Stack:
     def __init__(self):
         self.items = []

     def isEmpty(self):
         return self.items == []

     def push(self, item):
         self.items.append(item)

     def pop(self):
         return self.items.pop()

     def peek(self):
         return self.items[len(self.items)-1]

     def size(self):
         return len(self.items)

隊列

隊列抽象數據類型由以下結構和操作定義。如上所述,隊列被構造爲在隊尾添加項的有序集合,並且從隊首移除。隊列保持 FIFO 排序屬性。 隊列操作如下:
- Queue() 創建一個空的新隊列。 它不需要參數,並返回一個空隊列。
- enqueue(item) 將新項添加到隊尾。 它需要 item 作爲參數,並不返回任何內容。
- dequeue() 從隊首移除項。它不需要參數並返回 item。 隊列被修改。
- isEmpty() 查看隊列是否爲空。它不需要參數,並返回布爾值。
- size() 返回隊列中的項數。它不需要參數,並返回一個整數。

作爲示例,我們假設 q 是已經創建並且當前爲空的隊列,則 Table 1 展示了隊列操作序列的結果。右邊表示隊首。 4 是第一個入隊的項,因此它 dequeue 返回的第一個項。
這裏寫圖片描述

Python實現隊列

我們爲了實現隊列抽象數據類型創建一個新類。和前面一樣,我們將使用列表集合來作爲構建隊列的內部表示。
我們需要確定列表的哪一端作爲隊首,哪一端作爲隊尾。Listing 1 所示的實現假定隊尾在列表中的位置爲 0。這允許我們使用列表上的插入函數向隊尾添加新元素。彈出操作可用於刪除隊首的元素(列表的最後一個元素)。回想一下,這也意味着入隊爲 O(n),出隊爲 O(1)。

class Queue:
    def __init__(self):
        self.items = []

    def isEmpty(self):
        return self.items == []

    def enqueue(self, item):
        self.items.insert(0,item)

    def dequeue(self):
        return self.items.pop()

    def size(self):
        return len(self.items)

deque雙端隊列

deque(也稱爲雙端隊列)是與隊列類似的項的有序集合。它有兩個端部,首部和尾部,並且項在集合中保持不變。deque 不同的地方是添加和刪除項是非限制性的。可以在前面或後面添加新項。同樣,可以從任一端移除現有項。在某種意義上,這種混合線性結構提供了單個數據結構中的棧和隊列的所有能力。
要注意,即使 deque 可以擁有棧和隊列的許多特性,它不需要由那些數據結構強制的 LIFO 和 FIFO 排序。這取決於你如何持續添加和刪除操作。
這裏寫圖片描述

Deque抽象數據類型

deque 抽象數據類型由以下結構和操作定義。如上所述,deque 被構造爲項的有序集合,其中項從首部或尾部的任一端添加和移除。下面給出了 deque 操作。

  • Deque() 創建一個空的新 deque。它不需要參數,並返回空的 deque。
  • addFront(item) 將一個新項添加到 deque 的首部。它需要 item 參數 並不返回任何內容。
  • addRear(item) 將一個新項添加到 deque 的尾部。它需要 item 參數並不返回任何內容。
  • removeFront() 從 deque 中刪除首項。它不需要參數並返回 item。deque 被修改。
  • removeRear() 從 deque 中刪除尾項。它不需要參數並返回 item。deque 被修改。
  • isEmpty() 測試 deque 是否爲空。它不需要參數,並返回布爾值。
  • size() 返回 deque 中的項數。它不需要參數,並返回一個整數。

例如,我們假設 d 是已經創建並且當前爲空的 deque,則 Table 1 展示了一系列 deque 操作的結果。注意,首部的內容列在右邊。在將 item 移入和移出時,跟蹤前面和後面是非常重要的,因爲可能會有點混亂。
這裏寫圖片描述

Python實現Deque

class Deque:
    def __init__(self):
        self.items = []

    def isEmpty(self):
        return self.items == []

    def addFront(self, item):
        self.items.append(item)

    def addRear(self, item):
        self.items.insert(0,item)

    def removeFront(self):
        return self.items.pop()

    def removeRear(self):
        return self.items.pop(0)

    def size(self):
        return len(self.items)

無序列表抽象數據類型

如上所述,無序列表的結構是項的集合,其中每個項保持相對於其他項的相對位置。下面給出了一些可能的無序列表操作。

  • List() 創建一個新的空列表。它不需要參數,並返回一個空列表。
  • add(item) 向列表中添加一個新項。它需要 item 作爲參數,並不返回任何內容。假定該 item 不在列表中。
  • remove(item) 從列表中刪除該項。它需要 item 作爲參數並修改列表。假設項存在於列表中。
  • search(item) 搜索列表中的項目。它需要 item 作爲參數,並返回一個布爾值。
  • isEmpty() 檢查列表是否爲空。它不需要參數,並返回布爾值。
  • size()返回列表中的項數。它不需要參數,並返回一個整數。
  • append(item) 將一個新項添加到列表的末尾,使其成爲集合中的最後一項。它需要 item
    作爲參數,並不返回任何內容。假定該項不在列表中。
  • index(item) 返回項在列表中的位置。它需要 item 作爲參數並返回索引。假定該項在列表中。
  • insert(pos,item) 在位置 pos 處向列表中添加一個新項。它需要 item
    作爲參數並不返回任何內容。假設該項不在列表中,並且有足夠的現有項使其有 pos 的位置。
  • pop() 刪除並返回列表中的最後一個項。假設該列表至少有一個項。
  • pop(pos) 刪除並返回位置 pos 處的項。它需要 pos 作爲參數並返回項。假定該項在列表中。

Python實現無須鏈表

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, newdata):
        self.next = newdata


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

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

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

    def size(self):
        current = self.head
        count = 0
        while current != None:
            count += 1
            current = current.getNext()
        return 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

    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())

有序列表抽象數據結構

我們現在將考慮一種稱爲有序列表的列表類型。例如,如果上面所示的整數列表是有序列表(升序),則它可以寫爲 17,26,31,54,77和93。由於 17 是最小項,它佔據第一位置。同樣,由於 93 是最大的,它佔據最後的位置。
有序列表的結構是項的集合,其中每個項保存基於項的一些潛在特性的相對位置。排序通常是升序或降序,並且我們假設列表項具有已經定義的有意義的比較運算。許多有序列表操作與無序列表的操作相同。

  • OrderedList() 創建一個新的空列表。它不需要參數,並返回一個空列表。
  • add(item) 向列表中添加一個新項。它需要 item 作爲參數,並不返回任何內容。假定該 item 不在列表中。
  • remove(item) 從列表中刪除該項。它需要 item 作爲參數並修改列表。假設項存在於列表中。
  • search(item) 搜索列表中的項目。它需要 item 作爲參數,並返回一個布爾值。
  • isEmpty() 檢查列表是否爲空。它不需要參數,並返回布爾值。
  • size()返回列表中的項數。它不需要參數,並返回一個整數。
  • index(item) 返回項在列表中的位置。它需要 item 作爲參數並返回索引。假定該項在列表中。
  • pop() 刪除並返回列表中的最後一個項。假設該列表至少有一個項。
  • pop(pos) 刪除並返回位置 pos 處的項。它需要 pos 作爲參數並返回項。假定該項在列表中。

    總結

  • 線性數據結構以有序的方式保存它們的數據。
  • 棧是維持 LIFO,後進先出,排序的簡單數據結構。
  • 棧的基本操作是 push,pop和 isEmpty。
  • 隊列是維護 FIFO(先進先出)排序的簡單數據結構。
  • 隊列的基本操作是 enqueue,dequeue 和 isEmpty。
  • 前綴,中綴和後綴都是寫表達式的方法。
  • 棧對於設計計算解析表達式算法非常有用。
  • 棧可以提供反轉特性。
  • 隊列可以幫助構建定時仿真。
  • 模擬使用隨機數生成器來創建真實情況,並幫助我們回答“假設”類型的問題。
  • Deques 是允許類似棧和隊列的混合行爲的數據結構。
  • deque 的基本操作是 addFront,addRear,removeFront,removeRear 和 isEmpty。
  • 列表是項的集合,其中每個項目保存相對位置。
  • 鏈表實現保持邏輯順序,而不需要物理存儲要求。
  • 修改鏈表頭是一種特殊情況。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章