Chapter03

962 views

Published on

這是資料結構第三章 odp 檔,stack and queue。

Published in: Technology, Business
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
962
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
21
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Chapter03

  1. 1. Chapter 3 Stacks and Queues 3.1 Templates in C++ 3.2 The Stack Abstract Data Type 3.3 The Queue Abstract Data Type 3.4 Subtyping and Inheritance in C++ 3.5 A Mazing Problem 3.6 Evaluation of Expressions 3.7 Multiple Stacks and Queues
  2. 2. 3.1 Templates in C++ <ul><li>首先介紹 C++ 的 template functions 與 template classes </li></ul>3.1.1 Templates Functions <ul><li>Program 1.6 是對整數陣列作 selection sort ,若是要對 float 或 char 作 selection sort ,必須將其中的變數改成其他的資料結構。
  3. 3. A template may be viewed as a variable that can be instantiated to any data type, irrespective of whether this data type is a fundamental C++ type or a user-defined type.
  4. 4. template 又稱為 parameterized type. </li></ul>
  5. 5. 3.1 Templates in C++ template < class KeyType> void sort(KeyType *a, int n) { // 作非遞減排序 for ( int i = 0; i < n; i++) { int j = i; for ( int k = i + 1; k < n; k++) // 找出最小元素位置 if (a[k] < a[ j]) j = k; KeyType temp = a[i]; a[i] = a[j]; a[j] = temp; } } // Program 3.1 Selection sort using templates
  6. 6. 3.1 Templates in C++ float farray[100]; int intarray[250]; ... sort(farray, 100); sort(intarray, 250); <ul><li>可以用前面的程式碼來作 float 與 int 的排序。
  7. 7. 若 KeyType 是基本資料結構,則如此寫已足夠;若是 KeyType 是程式設計者自訂的資料結構,就需要針對 < 作運算子重載,也需要對 = 作運算子重載或給 copy constructor 。 </li></ul>
  8. 8. 3.1 Templates in C++ 3.1.2 Using Templates to Represent Container Classes <ul><li>A container class is a class that represents a data structure that contains or stores a number of data objects. </li></ul>template < class Type> class Bag { public : Bag( int MaxSize = DefaultSize); ~Bag(); void Add( const Type&); Type *Delete(Type&); Boolean IsFull(); Boolean IsEmpty(); private : void Full(); void Emplty(); Type *array; int MaxSize; int top; };
  9. 9. 3.1 Templates in C++ template < class Type> Bag<Type>::Bag( int MaxBagSize): MaxSize(MaxBagSize) { array = new Type[MaxSize]; top = -1; } template < class Type> Bag<Type>::~Bag() { delete [] array; } template < class Type> void Bag<Type>::Add( const Type& x) { if (IsFull()) Full(); else array[++top] = x; } // 定義在類別外面的成員函式,每一個函式都加上 template <class Type> 宣告方法 Bag < int > a(3); Bag <Rectangle> r(10);
  10. 10. D A B C 3.2 The Stack Abstract Data Type <ul><li>Ordered list A = a 0 ,a 1 ,..., a n-1 , 其中的 a i 稱為 atom 或 element 。 The null or empty list, denoted by (), has n = 0 elements.
  11. 11. Stack : Last-In-First-Out(LIFO) list
  12. 12. A stack is an ordered list in which insertions and deletions are made at one end called the top . 例如:插入 A,B,C,D ,刪除一個元素。
  13. 13. 令 S = (a 0 , a 1 , ..., a n-1 ) , a 0 is bottom, a n-1 is top, a i is on top of a i-1 , 0 < i < n. </li></ul>
  14. 14. 3.2 The Stack Abstract Data Type <ul><li>Example 3.1 [System stack]: 呼叫 function a1 之前與之後, system stack 的內容。 </li></ul>fp main previous frame pointer return address local variables fp a1
  15. 15. 3.2 The Stack Abstract Data Type template < class KeyType> class Stack { // objects: A finite ordered list of zero or more elements public : Stack ( int MaxStackSize = DefaultSize); Boolean IsFull(); // return TRUE if Stack is full; FALSE otherwise Boolean IsEmpty(); // return TRUE if Stack is empty; FALSE otherwise void Add(const KeyType &); // if IsFull(), return 0; // else insert an element to the top of the Stack KeyType *Delete( KeyType &); // if IsEmpty(), then return 0; // else remove and return a pointer to the top element }; // Abstract data type Stack , member function 的部份
  16. 16. 3.2 The Stack Abstract Data Type template < class KeyType> class Stack{ // data member 的部份 ... private : int top; KeyType *stack; int MaxSize; }; template < class KeyType> // 建構子 Stack <KeyType> :: Stack ( int MaxStackSize):MaxSize(MaxStackSize) { stack = new KeyType [MaxSize]; top = -1; }
  17. 17. 3.2 The Stack Abstract Data Type template < class KeyType > inline Boolean Stack< KeyType >:: IsFull (){ if (top == MaxSize – 1) return TRUE; else return FALSE; } template < class KeyType > inline Boolean Stack< KeyType >:: IsEmpty (){ if (top == -1) return TRUE; else return FALSE; }
  18. 18. 3.2 The Stack Abstract Data Type template < class KeyType> void Stack< KeyType >:: Add ( const KeyType& x ){ // add x to stack if ( IsFull() ) StackFull(); else stack[++top] = x ; } template < class KeyType> KeyType* Stack<Keytype>:: Delete (KeyType& x) { // Remove top element from stack if (IsEmpty() ) { StackEmpty(); return 0;} x = stack[top--]; return ( & x ); }
  19. 19. Exercises 3.2 2. Consider the railroad switching network given in Figure 3.3. Raidroad cars numbered 1, 2, 3, ..., n are initially in the top right track segment (in this order, left to right). Railroad cars can be moved into the vertical track segment one at a time from either of the horizontal segments and then moved from the vertical segment to any one of the horizontal segments. The vertical segment operates as a stack as new cars enter at the top and cars depart the vertical segment from the top. For instance, if n = 3, we could move car 1 into the vertical segment, move 2 in, move 3 in, and then take the cars out producing the new order 3, 2, 1. For n = 3 and 4 what are the possible permutations of the cars that can be obtained? Are any permutations not possible ?
  20. 20. 3.3 The Queue Abstract Data Type <ul><li>A queue is an ordered list in which all insertions take place at one end and all deletions take place at the opposite end.
  21. 21. First-In-First-Out (FIFO)
  22. 22. Example </li></ul><ul><ul><li>A queue Q = (a 0 , a 1 , ..., a n-1 ),
  23. 23. a 0 is the front element, a n-1 is the rear element,
  24. 24. a i is behind a i-1 , 1 ≤ i ≤ n. </li></ul></ul>B C D E A f r r r r r f
  25. 25. 3.3 The Queue Abstract Data Type <ul><li>用一維陣列與兩個變數來實作 queue , front 指著比第一個元素少 1 的位置, rear 指著最後一個元素的位置。
  26. 26. 資料成員: </li></ul>private : int front, rear; KeyType *queue; int MaxSize; <ul><li>建構子: </li></ul>template < class KeyType> Queue<KeyType>:: Queue ( int Max):MaxSize(Max) { queue = new KeyType[MaxSize]; front = rear = -1; }
  27. 27. 3.3 The Queue Abstract Data Type <ul><li>成員函式 </li></ul>template < class KeyType> inline Boolean Queue<KeyType>:: IsFull () { if (rear == MaxSize – 1) return TRUE; else return FALSE; } // 未必真的滿,因 front 很可能大於 -1 template < class KeyType> inline Boolean Queue<KeyType>:: IsEmpty () { if (front == rear) return TRUE; else return FALSE; }
  28. 28. 3.3 The Queue Abstract Data Type <ul><li>成員函式 </li></ul>template < class KeyType> void Queue<KeyType>:: Add ( const KeyType& x) { if (IsFull()) QueueFull(); else queue[++rear] = x; } template < class KeyType> KeyType* Queue<KeyType>:: Delete (KeyType& x) { if (IsEmpty()) {QueueEmpty(); return 0;} x = queue[++front]; return x; }
  29. 29. 3.3 The Queue Abstract Data Type Figure 3.5 Insertion and deletion from a queue front rear Q[0] [1] [2] [3] [4] [5] [6]... Comments -1 -1 queue empty initial -1 0 J1 J1 joins Q -1 1 J1 J2 J2 joins Q -1 2 J1 J2 J3 J3 joins Q 0 2 J2 J3 J1 leaves Q 0 3 J2 J3 J4 J4 joins Q 1 3 J3 J4 J2 leaves Q front rear Q[0] [1] [2] ...... [n-1] Next Operation -1 n-1 J1 J2 J3 ...... Jn initial state 0 n-1 J2 J3 ...... Jn delete J1 -1 n-1 J2 J3 J4 ...... Jn+1 add Jn+1 (J2 through Jn are moved) 0 n-1 J3 J4 ...... Jn+1 delete J2 -1 n-1 J3 J4 J5 ...... Jn+2 add Jn+2 Figure 3.6 Queue example
  30. 30. 3.3 The Queue Abstract Data Type <ul><li>Circular Queue ,將 Queue 想像成環狀,使用上會更有效率。 </li></ul>J4 J3 J2 J1 [4] [3] [2] [1] [0] [n-1] [n-2] [n-3] [n-4] [n-5] front = 0, rear = 4 J4 J3 J2 J1 [4] [3] [2] [1] [0] [n-1] [n-2] [n-3] [n-4] [n-5] front = n-4, rear = 0
  31. 31. 3.3 The Queue Abstract Data Type <ul><li>成員函式 </li></ul>template < class KeyType > void Queue< KeyType >:: Add ( const KeyType& x ) // add x to the circular queue { int newrear=(rear+1)% MaxSize; if ( front == newrear) QueueFull(); else queue[rear = newrear] = x ; } // 先用餘數運算算出新的 rear 值。 <ul><li>少存一個資料,如此才能分別出 full 與 empty 的差別 </li></ul>
  32. 32. 3.3 The Queue Abstract Data Type <ul><li>成員函式 </li></ul>template < class KeyType > KeyType *Queue< KeyType >:: Delete ( KeyType & x ) // remove front element from queue { if ( front == rear ) { QueueEmpty(); return 0; } front = (front + 1) % MaxSize; x = queue[front]; return & x ; } <ul><li>QueueFull 與 QueueEmpty 兩個函式與 StackFull 與 StackEmpty 類似。 </li></ul>
  33. 33. 3.4 Subtyping and Inheritance in C++ <ul><li>Inheritance is used to express subtype relationships between ADTs.
  34. 34. A data object of Type B IS- A data object of Type A if B is more specialized than A or A is more general than B. The set of all objects of Type B is a subset of the set of all objects of Type A.
  35. 35. 例如:椅子是家具、獅子是哺乳動物、矩形是多邊形
  36. 36. Stack IS-A Bag or Stack is a subtype of Bag.
  37. 37. C++ provides a mechanism to express the IS-A relationship called public inheritance .
  38. 38. class Stack: public Bag { // Bag 是 base class, Stack 是 derived class </li></ul>Stack( int MaxSize = DefaultSize); ~Stack(); int * Delete( int &); }
  39. 39. 3.4 Subtyping and Inheritance in C++ class Bag { public : Bag( int MaxSize = DefaultSize); virtual ~Bag(); virtual void Add( int ); virtual int * Delete( int &); virtual Boolean IsFull(); virtual Boolean IsEmpty(); protected : virtual void Full(); virtual void Empty(); int *array, MaxSize, top; }; class Stack: public Bag { Stack( int MaxSize = DefaultSize); ~Stack(); int * Delete( int &); }
  40. 40. 3.4 Subtyping and Inheritance in C++ <ul><li>The derived class inherits all the non-private memebers(data and functions) of the base class.
  41. 41. Another important consequence of public inheritance is that inherited members have the same level of access in the derived class as they did in the base class. </li></ul>Stack::Stack ( int MaxStackSize) :Bag(MaxStackSize) { } Stack::~Stack() { } // 直接呼叫 Bag 的解構子 int * Stack::Delete( int & x) { if (IsEmpty()) {Empty(); return 0;} x = array[top--]; return &x; }
  42. 42. 3.4 Subtyping and Inheritance in C++ Bag b(3); Stack s(3); //Stack 裡面的建構子 b.Add(1); b.Add(2); b.Add(3); // 使用 Bag::Add s.Add(1); s.Add(2); s.Add(3); // 使用 Bag::Add int x; b.Delete(x); // 呼叫 Bag::Delete s.Delete(x); // 呼叫 Stack::Delete ,使用 Bag::IsEmpty, Bag::Empty <ul><li>之後 s 中剩下 1, 2 兩個元素;而 b 中剩下 1, 3 兩個元素(因為其 delete 是從中間開始刪起 ) </li></ul>
  43. 43. 3.5 Amazing Problem <ul><li>將 rat 放在 maze 中,大部份的方向都不能走,只留下幾個可以走的方向,讓老鼠從入口走到出口。
  44. 44. 多訓練幾次,可算出老鼠的學習曲線。
  45. 45. 可用程式來模擬,只是理論上,程式應該第二次就可以將完全正確的路徑記起來。 </li></ul>entrance exit
  46. 46. 3.5 Amazing Problem <ul><li>Maze </li></ul><ul><ul><li>Represent by a two-dimensional array, maze[i][j], 1 ≤ i ≤ m, 1 ≤ j ≤ p.
  47. 47. maze[i][j] = 0 代表可走的路徑
  48. 48. maze[i][j] = 1 代表不可走的路徑 , blocked path
  49. 49. maze[1][1] 是入口 (entrance) ,而 maze[m][p] 是出口 (exit) </li></ul></ul><ul><li>若 rat 的位置是在 row i 與 column j ( 也就是 maze[i][j]) ,其可移動的方向如下圖 </li></ul>
  50. 50. 3.5 Amazing Problem X 西北 NW 北 N 東北 NE 東 E 東南 S E 南 S 西南 SW 西 W [ i – 1 ][ j – 1 ] [ i - 1 ][ j ] [ i - 1 ][ j + 1 ] [ i ][ j + 1 ] [ i + 1 ][ j + 1 ] [ i + 1 ][ j ] [ i + 1 ][ j – 1 ] [ i ][ j – 1 ] [ i ][ j ]
  51. 51. 3.5 Amazing Problem q move[q].a move[q].b N -1 0 NE -1 1 E 0 1 SE 1 1 S 1 0 SW 1 -1 W 0 -1 NW -1 -1
  52. 52. 3.5 Amazing Problem <ul><li>並不是每個位置都有八個方向可走,當在邊緣時 (i = 1, m or j = 1, p) 可走的方向就較少。
  53. 53. 可以用 maze[m+2][p+2] 的陣列來模擬迷宮,最外圈全部都設為 1 ,這樣就不用考慮邊緣的情形。
  54. 54. 可事先定義下列 structure ,以簡化運算 </li></ul>struct offsets { int a, b; } move[8]; enum directions {N, NE, E, SE, S, SW, W, NW}; <ul><li>若目前在位置 [i][j] ,要往西南方走,下一步位置為 [g][h] g = i + move[SW].a; h = j + move[SW].b; </li></ul>
  55. 55. 3.5 Amazing Problem initialize stack to the maze entrance coordinates and direction east; while ( stack is not empty) { ( i , j , dir ) = coordinates and direction deleted from top of stack ; while (there are more moves) { ( g , h ) = coordinates of next move; if (( g == m ) && ( h == p )) success; if (! maze [ g ][ h ]) && (! mark [ g ][ h ]) { // 有路走且尚未走過 mark [ g ][ h ] = 1; dir = next direction to try; add( i , j , dir ) to top of stack ; i = g; j = h; dir = north ; } } } cout << &quot;no path found&quot; << endl;
  56. 56. 3.5 Amazing Problem <ul><li>每個點都從北方開始、順時鐘方向嘗試
  57. 57. 用 mark[m+2][p+2] 來記錄是否走過, initialize 為 0 ,走過就設為 1
  58. 58. maze[1][1] 與 maze[m][p] 都為 0 。
  59. 59. 要將前面的演算法實作出來,還需要一個 stack ,這個 stack 最多有 mp 個元素 ( 最長路徑的長度,每個位置都放到 stack 中 ) ,實際上可能沒那麼多,但可能到 m/2 (p – 2) + 2
  60. 60. Stack 的每一項可定義如下: </li></ul>struct items { int x, y, dir; };
  61. 61. void path( int m, int p) { mark[1][1] = 1; Stack<items> stack(m*p); items temp; temp.x = 1; temp.y = 1; temp.dir = E; stack.Add(temp); while (!stack.IsEmpty()) { temp = *stack.Delete(temp); int i = temp.x; int j = temp.y; int d = temp.dir; while (d < 8) { int g = i + move[d].a; int h = j + move[d].b; if ((g == m) && (h == p)) { cout << stack; cout << i << &quot; &quot; << j << endl; cout << m << &quot; &quot; << p << endl; return ; } if ((!maze[g][h]) && (!mark[g][h])) { mark[g][h] = 1; temp.x = i; temp.y = j; temp.dir = d + 1; stack.Add(temp); i = g; j = h; d = N; } else d++; } } cout << &quot;no path in maze&quot; << endl; }
  62. 62. 3.5 Amazing Problem <ul><li>這個程式需要花多少時間?
  63. 63. 裡面的 while 迴圈最多跑八次,每次都是 constant time ,因此整個 while 迴圈是 constant time 。
  64. 64. 外面的 while 迴圈最多就是每個點都放到 stack 一次,因此 time complexity 就是 O(mp) 。
  65. 65. 真正作老鼠走迷宮的實驗時,可以在出口的地方放 cheese ,用以吸引老鼠跑快一點,用電腦模擬如何將這種變因考慮在內呢?有辦法找到最短路徑嗎?
  66. 66. 參考習題: 2. What is the maximum path length from start to finish for any maze of dimensions m * p? </li></ul>
  67. 67. 3.6 Evaluation of Expressions 3.6.1 Expressions <ul><li>How to generate machine-language instructions to evaluate an arithmetic expression? </li></ul>X = A / B – C + D * E – A * C <ul><li>An expression consists of </li></ul><ul><ul><li>Operands: A, B, C, D, E, true, false, 3.25, ...
  68. 68. Operators: +, –, *, /, %, >, < , ==, >=, <=, !=, &&, ||, !, ...
  69. 69. Delimiter: 如 (, ) </li></ul></ul>
  70. 70. 3.6 Evaluation of Expressions <ul><li>Priority ( 假設 A = 4, B = C = 2, D = E = 3) </li></ul><ul><ul><li>X = A / B – C + D * E – A * C </li></ul></ul>= ((4 / 2) - 2) + (3 * 3) – (4 * 2) = 0 + 9 – 8 = 1 <ul><ul><li>可能程式設計者真正想要的是 </li></ul></ul>X = (4 / (2 – 2 + 3)) * ( 3 – 4) * 2 = (4 / 3) * (–1) * 2 = -2.6666667 應寫成 X = ((A / (B – C + D)) * (E – A) * C 才對
  71. 71. 3.6 Evaluation of Expressions <ul><li>每個運算子給一個優先順序,就可固定運算順序,括號中的優先順序最高,其餘的類似下表, 1 是優先順序最高。 </li></ul>priority operator 1 unary minus, ! // 單元運算優先順序最高 2 *, /, % 3 +, – 4 <, <=, >=, > 5 ==, != 6 && 7 || 除了優先順序之外,還要考慮 結合性 - 優先順序相同的運 算子是左邊先作或右邊先作呢 ? C++ 大部份都是左邊先作。
  72. 72. 3.6 Evaluation of Expressions 3.6.2 Postfix Notation <ul><li>Compiler </li></ul><ul><ul><li>Translates an expression into a sequence of machine codes
  73. 73. It first re-writes the expression into a form called postfix notation . </li></ul></ul><ul><li>Infix </li></ul><ul><ul><li>The operators come in-between the operands </li></ul></ul><ul><li>Postfix </li></ul><ul><ul><li>The operators appear after its operands </li></ul></ul><ul><li>Example </li></ul><ul><ul><li>Infix: A / B – C + D * E – A * C
  74. 74. Postfix: A B / C – D E * + A C * – </li></ul></ul>
  75. 75. 3.6 Evaluation of Expressions <ul><li>假設每次運算的結果都暫存在 T i 裡面,則 A B / C – D E * + A C * – 運算結果如下: </li></ul>operation postfix T 1 = A / B T 1 C – DE * + AC * – T 2 = T 1 – C T 2 DE * + AC * – T 3 = D * E T 2 T 3 + AC * – T 4 = T 2 + T 3 T 4 AC * – T 5 = A * C T 4 T 5 – T 6 = T 4 – T 5 T 6 (A / B) – (C + D) * (E – A) * C 之 postfix form 為 A B / C D + E A – * C * –
  76. 76. 3.6 Evaluation of Expressions <ul><li>用 postfix 來計算簡單很多,不需括號、不需用到優先順序,從左到右掃過,使用 stack 即可。 </li></ul>void eval(expression e) { Stack <token> stack; for (token x = NextToken(e); x != '#'; x = Nexttoken(e)) if (x is an operand) stack.Add(x); // 運算元放到 stack 中 else { // 拿出正確的運算元,將結果放回 stack remove the correct number of operands for operator x from stack; perform the operation x and store the result(if any) onto the stack; } } // Program 3.18: Evaluating postfix expressions
  77. 77. 3.6 Evaluation of Expressions 3.6.3 Infix to Postfix <ul><li>將 infix 型式的表示式轉換成執行順序相同的 postfix 表示式。 </li></ul><ul><ul><li>1. Fully parenthesize the expression.
  78. 78. 2.Move all operators so that they replace their corresponding right parentheses.
  79. 79. 3. Delete all parentheses. </li></ul></ul><ul><li>例如: A / B – C + D * E – A * C 的 fully parenthesize 為 ((((A / B) – C) + (D * E)) – (A * C))
  80. 80. 將每個括號裡的部份都改成 postfix ,即為 </li></ul>AB/ C– DE* + AC* –
  81. 81. 3.6 Evaluation of Expressions <ul><li>將 infix A + B * C 轉成 postfix A B C * + </li></ul>next token stack output ------------------------------------------------------- none empty none A empty A + + A B + AB * +* AB // 因 * 優先順序比 + 高 C +* ABC <ul><li>最後再將 stack 裡的資料輸出,結果: A B C * + </li></ul>
  82. 82. 3.6 Evaluation of Expressions <ul><li>將 infix A * (B + C) * D 轉成 postfix ABC + * D * </li></ul>next token stack output ------------------------------------------------------------------- none empty none A empty A * * A ( *( A // ( 的 icp 比 * 的 isp 高 B *( AB + *(+ AB // + 的 icp 比 ( 的 isp 高 C *(+ ABC ) * ABC+ // ( 與 ) 之間的部份全輸出 * * ABC+* // * 是左結合性 D * ABC+*D 最後再將 stack 裡的資料輸出,結果: ABC+*D *
  83. 83. 3.6 Evaluation of Expressions <ul><li>Left parenthesis </li></ul><ul><ul><li>Behaves as an operator with hight priority when it is not in stack, in-coming priority ( icp ) = 0
  84. 84. Behaves as an operator with low priority when it is in stack, in-stack priority ( isp ) = 8
  85. 85. Only the right parenthesis could cause it to get unstacked. </li></ul></ul><ul><li>Operators are taken out of the stack as long as their in-stack priority is numerically less than or equal to the in-coming priority of the new operator.
  86. 86. isp('#') = icp('#') = 8
  87. 87. 將 infix 轉成 postfix 的時間複雜度為 O(n) , n 為 token 數。 </li></ul>
  88. 88. void postfix(expression e) { Stack<token> stack; token y; stack.Add('#'); for (token x = NextToken(e); x != '#'; x = NextToken(e)) { if (x is an operand) cout << x; else if (x == ')' ) for (y = *stack.Delete(y); y != '('; y = *stack.Delete(y)) cout << y; else { for (y = *stack.Delete(y); isp(y) <= icp(x); y = *stack.Delete(y)) cout << y; stack.Add(y); stack.Add(x); } } while (!stack.IsEmpty()) cout << *stack.Delete(y); }
  89. 89. Exercises 3.6 <ul><li>Write the postfix form of the following expressions: </li></ul><ul><ul><li>A * B * C
  90. 90. – A + B – C + D
  91. 91. A * –B + C
  92. 92. (A + B) * D + E / (F + A * D) + C
  93. 93. A && B || C || ! (E > F) // 用 C++ 的 precedence
  94. 94. !(A && ! ((B < C) || (C > D))) || (C < E) </li></ul></ul>
  95. 95. Exercises 3.6 3. Another expression form that is easy to evaluate and is parenthesis-free is known as prefix. In this way of writing expressions, the operators precede their operands. For example: A * B / C ==> / * ABC A/B–C+D*E–A*C ==> – + – / ABC * DE * AC A * (B + C) / D – G ==> – / * A + BCDG <ul><ul><li>What is the prefix form of the expressions in Exercise 1.
  96. 96. Write an algorithm to evaluate a prefix expression e. (hint: Scan e right to left and assume that the leftmost token of e is '# ')
  97. 97. Write an algorithm to transform an infix expression e into its prefix equivalent. Assume that the input expression e begins with a '# ' and that the prefix expression should begin with a '# '. </li></ul></ul>
  98. 98. 3.7 Multiple Stacks and Queues <ul><li>兩個 stacks 放在同一個一維陣列 M[m] 時,一個由 M[0] 向上長、一個由 M[m-1] 向下長。
  99. 99. 若有 n 個 stacks 放在同一個陣列,就只好將 M[m] 切成 n 等份,如下圖。 </li></ul>M 0  m/n – 1   2m/n – 1  m – 1 b[0] b[1] b[2] b[n] t[0] t[1] t[2]
  100. 100. 3.7 Multiple Stacks and Queues <ul><li>其 insert 與 delete 的運算如下: </li></ul>template < class Type> void Add( const int i, const Type& x) { if (t[i] == b[i+1]) StackFull(i); else M[++t[i]] = x; } template < class Type> items* Delete( const int i, const Type& x) { if (t[i] == b[i]){ StackEmpty(i); return 0;} x = M[t[i]--]; return &x; } 只是 t[i] == b[i+1] 時,只是一個 stack 滿,並不是所有的 stacks 都滿,可能還有很多空間,只是若要用到所有的空間, insert 的速度會慢很多, O(m) 。
  101. 101. 3.7 Multiple Stacks and Queues b[0] t[0] b[1] t[1] b[i] t[i] b[i+1] t[i+1] b[i+2] t[j] b[j+1] b[n]

×