資料結構 05 棧和佇列

2021-10-03 15:32:23 字數 4484 閱讀 2880

棧和佇列主要用於儲存臨時資料,例如階乘計算時的入棧保護。

: 先進後出 filo

佇列:先進先出 fifo

python中線性表可以作為棧和佇列的實現結構,list本身可以實現所有棧的操作,但是有些操作是棧沒有的,但是list可以,所以為了資料的安全性有必要對列表做一次外層的封裝來約束資料操作。

class

stackflowerror

(valueerror)

:pass

class

stack()

:def

__init__

(self)

: self._elem =

defis_empty

(self)

:return

len(self._elem )==0

defpush

(self, elem)

:def

pop(self)

:if self.is_empty():

raise stackflowerror(

'underflowerror'

)else

:return self._elem.pop(

)def

top(self)

:if self.is_empty():

raise stackflowerror(

'underflowerror'

)else

:return self._elem[-1

]def

elements

(self)

:# 按照filo的順序返回

while

not self.is_empty():

yield self.pop(

)if __name__ ==

'__main__'

: stack = stack(

)for i in

range(5

):stack.push(i)

for ele in stack.elements():

"""此處是倒敘輸出,也算是棧的乙個應用"""

print

(ele, end=

' ')

output:43

210

為什麼基於順序表實現後還有基於鏈結表實現呢?

1、順序表擴充代價高;

2、順序表需要完整的大塊儲存區;

所以小規模的資料還是基於list就好。

class

linkstackerror

(valueerror)

:pass

class

lnode()

:def

__init__

(self, elem,

next

=none):

self._elem = elem

self._next =

next

class

linkstack()

:def

__init__

(self)

: self._top =

none

defis_empty

(self)

:return self._top is

none

defpush

(self, elem)

: node = lnode(elem, self._top)

self._top = node

defpop(self)

:if self.is_empty():

raise linkstackerror

else

: ele = self._top._elem

self._top = self._top._next

return ele

deftop(self)

:return self._top._elem

lstack = linkstack(

)for i in

range(5

):lstack.push(i)

for i in

range(5

):print

(lstack.pop(

), end=

' ')

output:43

210

問題描述,在程式中(){}總要成對的出現,而且閉括號要與最近的前面的開括號配對,否則就是程式出了問題。

思路,類似於形式語言中的下推自動機,出現開括號就入棧,遇到閉括號就和棧頂配對

from list_stack import stack as stack

class

matcherror()

:pass

defcheck_parents

(text)

:"""檢查其括號是否正確配對"""

parents =

"(){}"

open_parents =

"(["

} parents_stack = stack(

) flag =

true

comment_flag =

false

for ele in text:

if ele ==

"#":

comment_flag =

true

if comment_flag ==

true

and ele ==

"\n"

: comment_flag =

false

ifnot comment_flag:

if ele in open_parents:

parents_stack.push(ele)

# 開括號壓棧

elif ele in parents:

if ele == parents_dict[parents_stack.pop()]

:# match

pass

else

: flag =

false

print

("match_error"

)break

if flag and parents_stack.is_empty():

print

("match_ok"

)else

:print

("缺少括號"

)check_parents(

"[hello(){}]#,2是可以在節點中增加路徑屬性,前驅對後繼採用增量賦值。

基本特徵:

1、一般為乙個初始狀態,乙個或者多個終止狀態;

2、在每乙個位置,要判斷下一步可行的位置;

3、找出乙個或者全部路徑。

可以採用遞迴或者回溯的方法求解,同類問題如:八皇后、騎士周遊問題。

狀態空間搜尋-棧和佇列

棧-後進先出,這意味著首先考慮的情況是最後進來的,棧中還儲存著一些沒探索的中間過程,只有當前出來的問題無解,才考慮回溯,換一條路徑搜尋。所以棧是深度優先搜尋。

佇列-先進先出,齊頭並進,廣度優先。

深度優先和廣度優先的性質

關於能否找到解:

深度優先:可能陷入區域性區域耗費很多時間,也有可能很快找到解

廣度優先:層層推進,只有存在到達解的有窮路徑,就可以找到解,而且最先找到的是最短路徑解。

關於路徑

基於棧-方便

基於隊-列需要另外記錄,可能技術代價很大。

關於可行解和最優解:

基於佇列-第乙個接是最優解

基於棧-找到所有解才能確定最優解

時間開銷:正比於搜尋過的位置,每一次是o(1)

空間開銷:廣度優先可能虧有很大開銷

總結:考慮解、空間開銷

python的collection本身與deque,使用雙端列表實現的雙端佇列,支援兩側的出入列,以及在兩端擴充一些元素。參考python手冊。

在實際計算機裡,能和新型cpu速度匹配的儲存器成本非常高,為了提高價效比,目前計算機採用分級快取結構,例如cpu要訪問單元d的資料,快取管理硬體會把d單元古今的連續單元複製到高階快取,如果後續操作基礎快取命中可以提高效率,所以對希望計算機記憶體使用區域性化,所以應該盡量使用順序表。鏈結表靈活的代價是效率。

資料結構與演算法05 棧 佇列

特點在於只能允許在容器的一端 稱為棧頂端指標,英語 top 進行加入資料 英語 push 和輸出資料 英語 pop 的運算。後進先出 lifo,last in first out 棧描述的是操作,線性表描述的是資料存放鍊錶 操作頭部 順序表 操作尾部 return self.list 是不太合適的 ...

資料結構 05棧

只能在表的同一端進行插入和刪除操作,且操作遵循先進後出原則的線性表稱為棧。若用 s a1,a 2,a3 an s a 1,a 2,a 3,a n s a1 a2 a3 an 表示棧,則 棧常見的兩種操作 棧的基本操作用順序儲存方式儲存元素的棧稱為順序棧。棧指標的設定及棧空 棧滿判斷 順序棧的初始化 ...

資料結構 棧和佇列

棧 基礎 知識棧 練習題 佇列 基礎知識 棧示意圖 後進先出 順序棧結構定義 define maxsize 1024 struct stack 操作函式 push 入棧 pop 出棧 struct lstack 鏈棧示意圖 操作函式 push 入棧 pop 出棧 注意 也可以直接呼叫系統已經寫好的庫...