四四、堆疊與佇列堆疊與佇列 (stack & queue)(stack &...

30
堆疊與佇列 (Stack & Queue) 堆疊與佇列 (Stack & Queue) 4-1. 串列及鏈結串列 4-2. 用陣列結構實作堆疊 4-3. 用鏈結串列實作堆疊 4-4. 堆疊的應用 4-5. 佇列 4-6. 用陣列結構實作佇列 4-7 用鏈結串列實作佇列 4 7. 用鏈結串列實作佇列

Upload: others

Post on 30-Jan-2020

8 views

Category:

Documents


0 download

TRANSCRIPT

  • 四、堆疊與佇列 (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