1. 程式人生 > >棧和佇列的應用相關習題及詳解 ——資料結構

棧和佇列的應用相關習題及詳解 ——資料結構

習題部分

選擇題

第一題

一個問題的遞迴演算法求解和其相對應的非遞迴演算法求解()
A. 遞迴演算法通常高效一些 B. 非遞迴演算法通常高效一些
C. 兩者相同 D. 無法比較

第二題

執行()操作時,需要使用佇列作為輔助儲存空間
A. 查詢雜湊(雜湊)表 B. 廣度優先搜尋圖
C. 前序(根)遍歷二叉樹 D. 深度優先搜尋圖

第三題

已知操作符包括‘+’‘-’‘’‘/’‘(’‘)’ 。將中綴表示式a+b-a((c+d)/e-f)+g轉化為等價的字尾表示式ab+acd+e/f-*-g+時,用棧來存放暫時還不能確定運算次序的操作符。若棧初始時為空,則轉換過程中同事儲存在棧中的操作符的最大個數是()

A. 5 B. 7
C. 8 D. 11

第四題

假設棧初始為空,將中綴表示式a/b+(c*d-e*f)/g轉化為等價的狗追表示式的過程中,當掃描到f時,棧中的元素依次是()

A. +(*- B. +(-* C. /+(*-* D. /+-*

解答部分

第一題

通常情況下,遞迴演算法在計算機實際執行的過程中包含很多的重複計算,所以效率會低

第二題

圖的廣度優先搜尋類似於樹的層序遍歷,同樣需要藉助於佇列

第三題

考察棧在種豬表示式轉化為字尾表示式中的應用。

將中綴表示式a+b-a*((c+d)/e-f)+g轉換為相應的字尾表示式,需要根據操作符<op>

的優先順序來進行棧的變化,我們用icp來表示當前掃描到的運算子ch的優先順序,該運算子進棧後的優先順序為isp,則運算子的優先順序如下表所示:

isp)是棧內優先(in stack priority)數,icp是棧外優先(in coming priority)數。

操作符 # ( *,/ +,- )
isp 0 1 5 3 6
icp 0 6 4 2 1

我們在表示式後面加上‘#’,表示表示式結束,具體換換過程如下:

步驟 掃描項 項型別 動作 棧內內容 輸出
isp 0 1 5 3 6
icp 0 6 4 2 1
0 #進棧,讀下一符號 #
1 a 運算元 直接輸出 # a
2 + 操作符 isp(‘#’) < icp(‘+’),進棧 #+
3 b 運算元 直接輸出 #+ b
4 - 操作符 isp(‘+’) > icp(‘-‘),退棧並輸出 # +
5 isp(‘#’) < icp(‘-‘),進棧 #-
6 a 運算元 直接輸出 #- a
7 * 操作符 isp(‘-‘) < icp(‘*’)進棧 #-*
8 ( 操作符 isp(‘*’) < icp(‘(‘),進棧 #-*(
9 ( 操作符 isp(‘(‘) < icp(‘(‘),進棧 #-*((
10 c 運算元 直接輸出 #-*(( c
11 + 操作符 isp(‘(‘) < icp(‘+’),進棧 #-*((+
12 d 運算元 直接輸出 #-*((+ d
13 ) 操作符 isp(‘+’) > icp(‘)’),退棧並輸出 #-*(( +
14 isp(‘(‘) == icp(‘)’),直接退棧 #-*(
15 / 操作符 isp(‘(‘) < icp(‘/’),進棧 #-*(/
16 e 運算元 直接輸出 #-*(/ e
17 - 操作符 isp(‘/’) > icp(‘-‘),退棧並輸出 #-*( /
18 isp(‘(‘) < icp(‘-‘),進棧 #-*(-
19 f 運算元 直接輸出 #-*(- f
20 ) 操作符 isp(‘-‘) > icp(‘)’),退棧並輸出 #-*( -
21 isp(‘(‘) == icp(‘)’),直接退棧 #-*
22 + 操作符 isp(‘*’) > icp(‘+’),退棧並輸出 #- *
23 isp(‘-‘) > icp(‘+’),退棧並輸出 # -
24 isp(‘#’) < icp(‘+’),進棧 #+
25 g 運算元 直接輸出 #+ g
26 # 操作符 isp(‘+’) > icp(‘#’),退棧並輸出 #
27 isp(‘#’) == icp(‘#’),退棧,結束

第四題

將中綴表示式轉換字尾表示式的演算法思想如下:
從左向右開始掃描中綴表示式;
遇到數字時,加入字尾表示式;
遇到運算子時:
a.若為‘(’,入棧;
b.若為‘)’,則一次把棧中的運算子加入字尾表示式中,直到出現‘(’,從棧中刪除‘(’;
c.若為除括號外的其他運算子,當其優先順序高於除‘(’意外的棧頂運算子時,直接入棧。否則從棧頂開始,一次彈出比當前處理的運算子優先順序高和優先順序相等的運算子,直到一個比它優先順序低的或者遇到了一個左括號位置。

當掃描的中綴表示式結束時,棧中的所有運算子一次出棧加入字尾表示式。

待處理序列 字尾表示式 當前掃描元素 動作
a/b+(c*d-e*f)/g a a加入字尾表示式
/b+(c*d-e*f)/g a / /入棧
b+(c*d-e*f)/g / a b b加入字尾表示式
+(c*d-e*f)/g / ab + +優先順序低於棧頂的/,彈出/
+(c*d-e*f)/g ab/ + +入棧
(c*d-e*f)/g + ab/ ( (入棧
c*d-e*f)/g +( ab/ c c加入字尾表示式
*d-e*f)/g +( ab/c * 棧頂為(,*入棧
d-e*f)/g +(* ab/c d d加入字尾表示式
-e*f)/g +(* ab/cd - -優先順序低於棧頂的,彈出
-e*f)/g +( ab/cd* - 棧頂為(,-入棧
e*f)/g +(- ab/cd* e e加入字尾表示式
*f)/g +(- ab/cd*e * *優先順序高於棧頂的-,*入棧
f)/g +(-* ab/cd*e f f加入字尾表示式
)/g +(-* ab/cd*ef ) 把棧中(之前的符號加入表示式
/g + ab/cd*ef*- / /優先順序高於棧頂的+,/入棧
g +/ ab/cd*ef*- g g加入字尾表示式
+/ ab/cd*ef*-g 掃描完畢,運算子一次退棧加入表示式
ab/cd*ef*-g/+ 完成

由此可知,當掃描到f的時候,棧中的元素一次是+(-*,選B。
再次再給出中綴表示式轉換為字首或字尾表示式的手工做法,以上面給出的中綴表示式為例:
第一步:按照運算子的優先順序對所有的運算單位加括號
式子變成了:((a/b)+(((c*d)-(e*f)/g))

第二部:轉換為字首或字尾表示式。
字首:把運算子號移動到對應的括號前面,則變成了:+(/(ab)/(-(*(cd)*(ef))g))
把括號去掉:+/ab/-*cd*efg字首式子出現
字尾:把運算子移動到對應的括號 後面,則變成了:((ab)/(((cd)*(ef)*)-g/)+
把括號去掉:ab/cd*ef*-g/+ 字尾式子出現

當題目要求直接求字首或字尾表示式時,這種方法會比上一中快捷的多。