棧和隊列的應用相關習題及詳解 ——數據結構


習題部分

選擇題

第一題

一個問題的遞歸算法求解和其相對應的非遞歸算法求解()
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/+ 後綴式子出現

當題目要求直接求前綴或後綴表達式時,這種方法會比上一中快捷的多。

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