Upload
others
View
11
Download
0
Embed Size (px)
Citation preview
四、堆疊與佇列 (Stack & Queue)四 堆疊與佇列 (Stack & Queue)4-1. 串列及鏈結串列4-2. 用陣列結構實作堆疊4-3. 用鏈結串列實作堆疊4-4. 堆疊的應用4-5. 佇列4-6. 用陣列結構實作佇列4-7 用鏈結串列實作佇列4 7. 用鏈結串列實作佇列
4-1 堆疊
堆疊的基本觀念
4 1 堆疊
1. 定義:當將東西疊成一堆,而取用的時候由上方來取出
2. 特性:先進後出,後進先出 (1號球先放,但3號球會先拿出)
12
3
3
1
2
4-1 堆疊
堆疊的運算
4 1 堆疊
1. push: 將資料放入堆疊2. pop: 將資料由堆疊最頂端取出一個p p3. TopItem: 位於堆疊中最上面的一個資料4 IsEmpty: 用來檢查目前堆疊是否為空4. IsEmpty: 用來檢查目前堆疊是否為空5. IsFull: 用來檢查目前堆疊是否已經滿了
hpush popIsFull
1
1 TopItemIsEmpty
TopItem
4-2 用陣列結構實作堆疊
範例:資料的宣告方式
4 2 用陣列結構實作堆疊Item[4]
堆疊的宣告int Item[5]; // 宣告一個堆疊共有5個位置
Item[3]
Item[2]
1. 放入資料push(A);
push(B);
Item[1]
Item[0]Item[4]
Item[3]push(B);push(C);
2. 取出資料
Item[3]
Item[2] CItem[1] BIt [4]x1 = pop(); // C
x2 = pop(); // B
3 放入資料
Item[1] BItem[0] A
Item[4]
Item[3]
It [2]
Item[4]
Item[3]3. 放入資料push(D);
Item[2]
Item[1]Item[2]
Item[1] DItem[0] A
Item[0] A
4-2 用陣列結構實作堆疊
範例:
4 2 用陣列結構實作堆疊
(1) (2) (3) (4)請填入堆疊的狀態
int Item[3];
1 執行下面指令
Item[2]
Item[1]
Item[0] A
Item[2]
Item[1] B
Item[0] A
Item[2] C
Item[1] B
Item[0] A
Item[2] C
Item[1] B
Item[0] A1. 執行下面指令(1) push(A);
(2) push(B);
Item[0] A Item[0] A Item[0] A
Item[2] Item[2] Item[2]
Item[0] A
Item[2]
(5) (6) (7) (8)
(3) push(C);
(4) push(D);
(5) x1 = pop();
Item[2]
Item[1] B
Item[0] A
Item[2]
Item[1]
Item[0] A
Item[2]
Item[1]
Item[0]
Item[2]
Item[1]
Item[0](5) pop();
(6) x2 = pop();
(7) x3 = pop();
(8) 4 pop()Item[2] Item[2] Item[2]
(9) (10) (11)Item[2]
(12)
(8) x4 = pop();
(9) push(E);
(10) x5 = pop();
Item[1]
Item[0] E
Item[1]
Item[0]
Item[1]
Item[0] F
Item[1] G
Item[0] F
(11) push(F);
(12) push(G);X1 = C、X2 = B、X3 = A、X4 = 0、X5 = E
4-3 用鏈結串列實作堆疊
範例:原始的堆疊為 50,21,10
4 3 用鏈結串列實作堆疊
執行pop()的指令執行push(12)的指令
x
5050
12x(1) 將原來指向50
的鏈結改成指向21
(1) 將12的鏈結指
x
2121
(1) 將12的鏈結指向50
1010
4-3 用鏈結串列實作堆疊
利用鏈結串列實作堆疊的優點
4 3 用鏈結串列實作堆疊
1. 不受堆疊長度的限制 (除非記憶體不足)可以動態的加入堆疊的元素
利用鏈結串列實作堆疊的缺點利用鏈結串列實作堆疊的缺點
1. 必需多一個儲存指標的欄位2 實作上較為複雜2. 實作上較為複雜
4-4 堆疊的應用
堆疊的應用主要為下列三項:
4 4 堆疊的應用
1. 副程式的呼叫與返回2. 運算式的轉換及求值3. 遞迴
4-4 堆疊的應用1.副程式的呼叫與返回範例:
4 4 堆疊的應用
主程式執行並呼叫兩個副程式,請寫出執行下面步驟後的『返回位址堆
疊』的內容?
主程式
開始 0000
0002
副程式10100
副程式20200
(1) 呼叫副程式1 (2) 呼叫副程式20002
0004
0006
0100
0102
0104
0200
0202
0204(4) 返回
結束
0008
000A
0106
0108
0206(3) 返回
2
1執行上面各步驟後返回位址堆疊
(1)
2
1 0106
(2)
2
1
(3)
2
1
(4)
1
0 0002
後返回位址堆疊的內容
1 0106
0 0002
1
0 0002
1
0
4-4 堆疊的應用2.運算式的轉換及求值:
4 4 堆疊的應用
(1) X = A + B * C – ( D + E / F )運算式: 等號的右邊稱為運算式運算子 (O t ) * /運算子 (Operator) : +, -, *, /運算元 (Operand) : A, B, C, D, E, F
(2)運算子的優先順序:(2)運算子的優先順序: (,) → *, /, % → +, - → >,
4-4 堆疊的應用2.運算式的轉換及求值:
4 4 堆疊的應用
中序式轉成後序表示法的步驟: A+B*C(1) 將相關的運算元用括號括起來
( A ( B * C ) )( A + ( B * C ) )
(2) 找到他右邊最接近的右括號,並加上箭號(2) 找到他右邊最接近的右括號,並加上箭號( A + ( B * C ) )
(3) 將運算子移到右括號的位置A B C * +
4-4 堆疊的應用2.運算式的轉換及求值: 範例(將下面的中序式轉成後序式)
4 4 堆疊的應用
(1) (A+B) * C – D / E (((A+B) * C) – (D/E))(( A B+ * C) D E/ )(( A B+ * C) – D E/ )( A B+ C* - D E/ )
A B+ C* D E/ -
(2) A + (B/C - D) * E – F/G((A + (((B/C) - D) * E)) – (F/G))((A + ((BC/ - D) * E)) – FG/ ) ((A + (BC/ D - * E)) – FG/ )((A + (BC/ D - E)) – FG/ ) ((A + BC/ D - E * ) – FG/ ) (A BC/ D - E * + – FG/ )A BC/ D - E * + FG/ -
4-4 堆疊的應用2.運算式的轉換及求值: 範例(將下面的中序式轉成後序式)
4 4 堆疊的應用
(3) (A+B) * (C – D) / E (((A+B) * (C – D)) / E )((AB+ * CD ) / E )((AB+ * CD-) / E )(AB+ CD- * / E )AB+ CD- * E /
(4) A + B*C - (E + F)((A + (B*C)) - (E + F))((A + B C*) - E F+)( A B C*+ E F+)( A B C*+ - E F+)A B C*+ E F+ -
4-4 堆疊的應用2.運算式的轉換及求值: 範例
4 4 堆疊的應用
計算下面的後序式的值 A=5, B=6, C=2, D=3, E=2, F=9, G=3(1) AB+CD- * E /
(11)CD * E /= (11)CD- * E /= (11)(-1) * E /= ( 11) E /= (-11) E / = -5.5
(2) ABC*+ E F+ -= A (12) + E F + -( )= (17) E F + -= (17) (11) –= 6
4-4 堆疊的應用2.運算式的轉換及求值: 範例
4 4 堆疊的應用
計算下面的後序式的值 A=5, B=6, C=2, D=3, E=2, F=9, G=3(3) AB+ C* D E/ -
= (11) C * D E /= (11) C * D E / -= (22) D E / -= (22) (1.5) –= 20.5
(4) ABC/ D - E * + FG/ -= A (3) D - E * + F G / -= A (0) E * + F G / -= A (0) + F G / -= A (0) + F G / = (5) F G / -= (5) (3) –= 2
4-4 堆疊的應用2.運算式的轉換及求值: 範例
4 4 堆疊的應用
使用堆疊法將下面中序轉後序式 (A+B) * C – D / E
次序 運算式 運算子堆疊(底 – 頂) 輸出的後序式1 ( (
2 A ( A
3 + (+ A3 + (+ A
4 B (+ AB
5 ) AB+
6 * * AB+
7 C * AB+C
8 AB+C*8 - - AB+C*
9 D - AB+C*D
10 / -/ AB+C*D
11 E
4-5 佇列
範例:
4 5 佇列
1.定義:
將東西排成一列,先到的先處理將東西排成一列 先到的先處理
2.特性:
先進先出 後進後出先進先出,後進後出
FrontRear FrontRear
210 B 210 AB
AB
4-5 佇列
佇列的運算
4 5 佇列
1. EnQueue: 將資料放入佇列2. DeQueue: 將資料由佇列的前端取出一個3. IsEmpty: 用來檢查目前佇列是否為空4 IsFull: 用來檢查目前佇列是否已經滿了4. IsFull: 用來檢查目前佇列是否已經滿了
EnQueue DeQueue
1
Q
1B 210 AB
FrontRear
4-6 用陣列結構實作佇列
佇列的宣告
4 6 用陣列結構實作佇列
typredef struct tagQUEUE{
char item[MAX ITEM]; // 假設 MAX ITEM = 7;char item[MAX_ITEM]; // 假設 MAX_ITEM 7;int front; // 下次將取出資料的地方int rear; // 本次已加入資料的地方
} QUEUE} QUEUE;
佇列的使用 Item[0] Item[1] Item[2] Item[3] Item[4] Item[5] Item[6]佇列的使用QUEUE q;q.Front = -1;
Item[0] Item[1] Item[2] Item[3] Item[4] Item[5] Item[6]
1 f t 1 此時表示佇列為空q.Rear = -1; rear = -1, front = -1 此時表示佇列為空
加入資料: rear 加 1,將新項目加入到 item[rear] 中取出資料: front 加 1,讀出 item[front] 中的資料
4-6 用陣列結構實作佇列
佇列的操作
4 6 用陣列結構實作佇列
1.加入資料q.EnQueue(A); // 加入 A
Item[0] Item[1] Item[2] Item[3] Item[4] Item[5] Item[6]
Aq ( )
加
rear = 0, front = -1Item[0] Item[1] Item[2] Item[3] Item[4] Item[5] Item[6]
q.EnQueue(B); // 加入 B A B
rear = 1, front = -1
q.EnQueue(C); // 加入 CItem[0] Item[1] Item[2] Item[3] Item[4] Item[5] Item[6]
A B C
rear = 2, front = -1
4-6 用陣列結構實作佇列
佇列的操作
4 6 用陣列結構實作佇列
Item[0] Item[1] Item[2] Item[3] Item[4] Item[5] Item[6]
2.取出資料str1 = q.DeQueue();
Item[0] Item[1] Item[2] Item[3] Item[4] Item[5] Item[6]
B C
rear = 2 front = 0q rear = 2, front = 0
Item[0] Item[1] Item[2] Item[3] Item[4] Item[5] Item[6]
Cstr2 = q.DeQueue();
C
rear = 2, front = 1
Item[0] Item[1] Item[2] Item[3] Item[4] Item[5] Item[6]str3 = q.DeQueue();
Item[0] Item[1] Item[2] Item[3] Item[4] Item[5] Item[6]
rear = 2 front = 2
q.EnQueue(D); // 加入 D
rear = 2, front = 2Item[0] Item[1] Item[2] Item[3] Item[4] Item[5] Item[6]
D
rear = 3, front = 2
4-6 用陣列結構實作佇列
環狀佇列
4 6 用陣列結構實作佇列
優點:
可以重複使用佇列的位置 7
Rear61 Front
Rear1
52
43
4-6 用陣列結構實作佇列4 6 用陣列結構實作佇列
利用陣列來模擬環狀佇列
A
判斷是否可以再加入資料:
210A
CBMaxSize = 3
3
F t R D
Rear = 2Front = 1
Front Rear D利用陣列來模擬環狀佇列(1) (Rear+1) Mod MaxSize = 3 Mod 0 = 0(2) 比較 Rear 和 Front 的值(2) 比較 Rear 和 Front 的值
Rear < Front 則可以放入資料Rear = Front 滿了!! 無法放入資料
4-6 用陣列結構實作佇列
MaxSize = 5 範例:
4 6 用陣列結構實作佇列
Rear = 3Front = 3表示目前為空
MaxSize = 6
Rear = 14F t 3表示目前為空
Rear = 4 (MaxSize)Front = 3
Front = 3
(1) 是否可以再放入資料Front = 3無法放入資料
利用陣列來模擬環狀佇列
(Rear + 1) % MaxSize =15 % 6 = 3Rear (3) = Front (3)利用陣列來模擬環狀佇列
(1) (Rear+1) Mod MaxSize = 5 Mod 5 = 0(2) 比較 Rear 和 Front 的值
Rear < Front 則可以放入資料
Rear (3) = Front (3)不可放入資料
(2) 放入的資料位置在何處Rear < Front 則可以放入資料Rear = Front 滿了!! 無法放入資料
0 < Front 可以放入資料
(2) 放入的資料位置在何處
不可放入資料可以放入資料
放入到 0 的位置
4-6 用陣列結構實作佇列
範例: 範例:
4 6 用陣列結構實作佇列
MaxSize = 5
Rear = 12F t 4
MaxSize = 7
Rear = 17F t 6Front = 4
(1) 是否可以再放入資料
Front = 6
(1) 是否可以再放入資料
(12+1) % 5 = 33 < 4可以再放資料
(17+1) % 7 = 44 < 6可以再放資料可以再放資料
(2) 放入的資料位置在何處
可以再放資料
(2) 放入的資料位置在何處
放在 3 的位置 放在 4 的位置
4-6 用陣列結構實作佇列
範例:
4 6 用陣列結構實作佇列
範例:MaxSize = 5
Rear = 31Rear = 31Front = 4
(1) 是否可以再放入資料(1) 是否可以再放入資料
(31+1) % 5 = 22 < 42 4可以再放資料
(2) 放入的資料位置在何處( )
放在 2 的位置
4-6 用陣列結構實作佇列32
queue
queue3
queue
4 6 用陣列結構實作佇列
210 Rear = -1Front = -1
3210 A R 0
B
3210 A
Rear = 1
使用函數 動作說明 Rear 值 Front 值
0 A Rear = 0Front = -1
0Front = -1
B
321 Rear = 1
EnQueue(A) 把 A 加到 0 的位置 0 -1
EnQueue(B) 把 B 加到 1 的位置 1 -1
0 Front = 0
C32 R 2
DeQueue() 取出 A 1 0
EnQueue(C) 把 C 加到 2 的位置 2 0
BC2
10
Rear = 2
Front = 0( )
DeQueue() 取出 B 2 1
DeQueue()
C321
Rear = 2Front = 1 DeQueue()
0
4-6 用陣列結構實作佇列
3
queue
4 6 用陣列結構實作佇列
3210
Rear = -1Front = -10 Front = -1
使用函數 動作說明 Rear 值 Front 值
EnQueue(A) 把 A 加到 0 的位置 0 -1
EnQueue(B) 把 B 加到 1 的位置 1 -1
DeQueue() 取出 A 1 0
EnQueue(C) 把 C 加到 2 的位置 2 0
DeQueue() 取出 B 2 1
DeQueue() 取出 C 2 2DeQueue() 取出 C 2 2
4-6 用陣列結構實作佇列
3
queue
B3 R 3queue
B3
queue
4 6 用陣列結構實作佇列
A3210
Rear = 2Front = 1
AB3
210
Rear = 3
Front = 1AB3
210 C
Front = 1Rear = 00
使用函數 動作說明 Rear 值 Front 值
0 0 C Rear 0
EnQueue(B) 把 B 加到 3 的位置 3 1
EnQueue(C) 把 C 加到 0 的位置 0 1
EnQueue(D) 把 D 加到 1 的位置 1 1
DeQueue() 取出 A 1 2()
EnQueue(E) 把 E 加到 2 的位置 2 2
D Q () 取出 B 2 3DeQueue() 取出 B 2 3
4-7 用鏈結串列實作佇列4 7 用鏈結串列實作佇列
rear front
20 28 36 45 NULL
ListA