數據結構和算法----隊列

隊列

  • 定義

通俗點的定義就是,排隊買票,先到的先買。就是先進先出。隊列和棧一樣都是操作受限的線性表數據結構

  • 入隊,出隊

在隊尾入隊,隊頭出隊。同樣想象買票的流程。除非你經常插隊要不很容易理解!

  • 實現方式

順序隊列:用數組實現的隊列

鏈式隊列:用鏈表實現的隊列

  • 時間複雜度

1、順序隊列的python代碼實現

首先說一下順序隊列的實現過程。與棧只需要一個棧頂指針不同,隊列需要兩個指針一個指向隊頭,一個指向隊尾。

在入隊和出隊操作之後,指針的位置就會後移,因數組的長度限制,當隊尾指向數組尾部下標的時候無法後移。如果出隊一次進行一次數據遷移就不會有這種問題,但是時間複雜度就會由O1)變爲O(n)。所以解決辦法就是當沒有空閒時間之後,才進行一次大的數據遷移。

 

如圖:紅色爲隊頭藍色爲隊尾。如果每操作一次出隊,就進行一次數據遷移,那麼時間複雜度就會變爲O(n),如果無法插入時再進行數據前移,那麼出隊的時間複雜度仍然是O(1)。入隊的時間複雜度就會由O(1),變爲n-1O(1)加上一次O(n)。均攤時間複雜度就是O(1).

python沒有數組,有列表,列表是由對其它對象的引用組成的連續數組。指向這個數組的指針及其長度被保存在一個列表頭結構中。這就意味着每次進行增刪操作都需要對數組的大小進行重新分配。這樣的結構在對列表進行操作時的時間複雜度會很高。爲了避免這種情況,這裏要引入分配槽的概念,分配槽的大小不等同於列表大小,分配槽大小是指在內存中已經分配了的槽空間數。這樣能避免每次列表添加數據都調用分配函數,這樣均攤的時間複雜度就會比較低。增長模式爲:04816253546587288……。所以python實現隊列並對隊列進行操作時,與正常數組實現的隊列不大一樣(因爲我的開發語言是python所以有時會對python一些特性進行分析)

python列表的特性,進行刪除操作時的時間複雜度爲O(N).所以在進行出隊時不要進行刪除操作。留到數據遷移時同時進行

  • 代碼實現
  1. 順序隊列
class queues:

    def __init__(self):

        self.items = []

        self._len = None

        self._head = 0

        self._taile = 0

    def _pop(self):

        if self.items:

            re_data = self.items[self._head]

            self._head = self._head + 1

            if self._head == 10:

                self._kuorong()

            return re_data

        else:

            return None

    def _push(self,data):

        self._taile = self._taile + 1

        self.items.append(data)

    def _kuorong(self):

        self.items = self.items[self._head:self._taile]

        self._head = 0

        self._taile = len(self.items)

 

     2.鏈式隊列

class Node(object):

    def __init__(self,data,next=None):

        self.data = data

        self.next = next

class equeue:

    def __init__(self):

        self.headnode = Node(None)

        self.rear = None

    def _push(self,data):

        NewNode = Node(data)

        if not self.rear:

            self.headnode.next = NewNode

            self.rear = NewNode

        else:

            self.rear.next = NewNode

            self.rear = NewNode

    def _pop(self):

        result = self.headnode.next

        if self.headnode.next:

            self.headnode.next = self.headnode.next.next

        else:

            return None

        return result.data

 

     3.循環隊列

class queues:

    def __init__(self):

        self.items = [None]*10

        self._len = None

        self._head = 0

        self._taile = 0

    def _pop(self):

        if self.items[self._head] != None:

            print(self.items[self._head])

            re_data = self.items[self._head]

            self.items[self._head] = None

            self._head = self._head + 1

            if self._head == 10:

                self._head = 0

            return re_data

        return None

    def _push(self,data):

        #print(self._taile,self.items[self._taile])

        if self.items[self._taile] == None:

            self.items[self._taile] = data

            self._taile = self._taile + 1

            if self._taile == 10:

                self._taile = 0

        else:

            #print("隊滿")

            pass

代碼是自己編的,都能實現功能。如果發現問題或有更優化的代碼請評論!!!

本文由博主學習總結而來,如果有錯誤的地方請指正。有多處借鑑!借鑑於

https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzI5OTIyMjQxMA==&scene=124#wechat_redirect

https://time.geekbang.org/column/article/40961

萬分感謝馬老師和王爭大佬的知識分享!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章