資料結構 佇列和雙端佇列及應用

2021-10-09 04:33:12 字數 3280 閱讀 7111

queue

佇列的特點就是fifo(first in first out),即先進先出,其新增資料項時僅新增到佇列的末尾,刪除資料時也僅從佇列首端刪除,其在日常有許多應用,比如排隊、鍵盤打字緩衝以及印表機等等。佇列在演算法中的應用最為基礎的就是hotpotato演算法。以下便是我在佇列學習中的總結。

首先來定義queue類:

class

queue

:def

__init__

(self)

: self.items =

#用list來裝載queue的資料

defis_empty

(self)

:return self.items ==

defsize

(self)

:return

len(self.items)

defenqueue

(self,new_item)

: self.items.insert(

0,new_item)

#list首端作為queue尾端,其尾端為queue首端(相當於把列表按照原順序直接倒過來)

defdequeue

(self)

:return self.items.pop(

)

之前學習中較為困惑的地方就是enqueue的實現,我們通過列表來體現佇列,而佇列的尾端剛好對應的就是列表的首端,二者反向是相反的,從佇列末尾新增資料項就相當於新增在列表首端,這是佇列較為特殊的地方。

接下來便是熱土豆演算法,hotpotato演算法的過程就是佇列首端的人拿到熱土豆並傳給後面的人,同時自己從首端轉移到佇列尾端,大家依次這樣做,等滿足需要傳遞的次數後,當前排在佇列首端的人會被淘汰,就這樣不斷迴圈,最終剩下的乙個人為倖存者。

def

hot_potato

(name_list,num)

:#num為傳遞次數

name_queue = queue(

)for i in name_list :

name_queue.enqueue(i)

#name_queue : rear['josef','kyrie','jordan','mike','bill']front

while name_queue.size(

)>1:

#佇列中只留乙個人

for i in

range

(num)

: name_queue.enqueue(name_queue.dequeue())

#移除隊首資料項的同時將其加入隊尾

name_queue.dequeue(

)#淘汰隊首資料項

return name_queue.dequeue(

)#返回最終倖存者

print

(hot_potato(

['bill'

,'mike'

,'jordan'

,'kyrie'

,'josef'],

5))

其執行結果為kyrie。

deque

雙端佇列可以通過首端和尾端新增或刪除資料項,可以當stack和queue的結合,但是還得通過操作者來實現棧和佇列的特性。其應用的基礎演算法問題則是回文檢測演算法,用於判斷一段字串中的字元是否對稱排列。先來定義雙端佇列:

class

deque

:def

__init__

(self)

: self.items =

#用列表來承載佇列的資料項

defis_empty

(self)

:return self.items ==

defsize

(self)

:return

len(self.items)

defadd_front

(self,new_item)

:#佇列首端(相當於列表尾端)新增資料項

defadd_rear

(self,new_item)

:#佇列尾端(相當於列表首端)新增資料項

self.items.insert(

0,new_item)

#列表首端用insert函式

defremove_front

(self)

:return self.items.pop(

)#記得返回其移除的資料項

defremove_rear

(self)

:return self.items.pop(0)

#同上,返回移除資料項

這裡對於我而言難點是對那四個新增刪除功能的理解,要理解列表和雙端佇列間的關係,其和佇列間的關係一樣,相當於把列表倒過來,資料項排列順序不變。

接著就是deque的應用-----回文檢測演算法,其核心思想就是利用雙端佇列兩頭出進的特性將字串字元彈出,如果該字串是回文字串則每次兩端彈出的兩個字元應該是相等的,這樣就可以判斷乙個字串是否為回文字串了。演算法**如下:

def

qal_checker

(string)

: char_deque = deque(

) still_equal =

true

for i in string :

#將字串中的字元新增到雙端佇列中

char_deque.add_rear(i)

while char_deque.size(

)>

1and still_equal :

first = char_deque.remove_front(

) last = char_deque.remove_rear(

)if first != last :

#彈出首尾資料項並判斷是否相等

still_equal =

false

return still_equal

print

(qal_checker(

"agbzbhub"))

print

(qal_checker(

"abaccaba"

))

執行結果分別為false和true。

參考資料:problem solving with algorithms and data structures using python

資料結構 佇列 雙端佇列

佇列 queue 是只允許在一端進行插入操作,而在另一端進行刪除操作的線性表。佇列是一種先進先出 first in first out 的線性表,簡稱fifo。允許插入的一端為隊尾,允許刪除的一端為對頭。佇列不允許在中間部位進行操作。假設佇列是q 那麼a1就是對頭元素,而an是隊尾元素。這樣我們就可...

資料結構 佇列 普通佇列和雙端佇列

佇列 queue 建立乙個空佇列 enqueue item 新增元素 dequeue 從佇列頭部刪除乙個元素 is empty 判斷乙個佇列是否為空 size 返回佇列的大小 class queue object 佇列 def init self self.items defis empty sel...

資料結構之雙端佇列

摘要 有時候乙個佇列可能需要能從兩端進出,這時候稱呼它為雙端佇列。具體思路很簡單,從 可以直接看出來。include stdafx.h include malloc.h include stdlib.h typedef struct dequeuerecord queue struct dequeu...