# 資結 第三章:stack與Queue [toc] ## stack定義、應用、製作 ### 定義 是一個具有LIFO(Last-In-First-Out)性質之有序串列 ### 製作 * Create * IsFull * IsEmpty * push * pop ### 製作方法 1.利用array製作 宣告: (1)S: array[1...n] of items; (2)Top: int=0; ``` push(s,item) { if(top == n) then return "full"; else { Top = Top + 1; S[Top] = item; } } pop(s) { if(isempty(s)) then return "empty"; else { item = S[Top]; Top = Top - 1; return item; } } ``` <font color="red">不管是push還是pop,時間都是花O(n)</font> 2.利用link list製作 (1) Node structure如下: |Data|Link| |---|---| Data欄:存資料 Link欄:pointer(指標)指向下一個Node位置 ``` Push(s,item) { new(t); t->Data = item; t->Link = Top; Top = t; } Pop(s) { if(Top == "Nil") return "empty"; else { t = Top; //指向最上層的空間,因top要往下指,需要一個人去接住沒人指的地方 item = Top->Data; Top = Top->Link; free(t); } } ``` <font color="red">不管是push還是pop,時間都是花O(1)</font> ## stack permutation ### 定義 將n個Data,依序push入stack中,但在過程中,可以穿插執行合法的pop,輸出Data,則n個Data輸出之排列組合,稱之 例如:a,b,c三個data之stack permutation為五種,cab不行 <font color="red">算法=$\dfrac{1}{n+1}{2n\choose n}$</font> |n|數目| |--|--| |3|5| |4|14| |5|42| |6|132| 同義: [1] n個nodes可以形成的不同Binary tree結構 [2] n個"("及n個")"的合法配對數 [3] <font color="red">n+1</font>個矩陣相乘之乘法配對組合順序 ### infix,postfix,prefix之轉接 * infix:中序 缺點:compiler不易直接求算infix之值,需考量優先權,結合性,導致可能來回多次式子掃描 * postfix:後序 優點:compiler只須由左而右掃描式子一次,即可求出結果 * prefix:前序 優點:compiler只須由右而左掃描式子一次,即可求出成果 缺點:infix轉prefix需要<font color="red">2</font>個stacks支持,但infix轉postfix只需一個stack支持 ### 計算題型 * infix轉postfix * infix轉prefix * postfix轉infix * prefix轉infix * infix轉posfix之algorithm * postfix evaluation algorithm * prefix evaluation algorithm(少考) * infix轉prefix algorithm(少考) ### compiler之parsing using stack * ()是否正確 * 輸入字串是否符合回文 * 判斷輸入字串是否符合a^n^b^n^(少考) ## Queue(佇列) ### 定義 是一個具有FIFO性質的有序串列 ### 應用 * os中各種queue * buffer設計 * 系統效能評估模擬 * 圖形的BFS * Binary tree的level-order traversal * 日常中排隊行為 ### 製作 一、利用array * 利用linear array 方法很爛,很浪費空間 * 利用circular array 最多利用n-1格 * 利用circular array 最多利用n格 法二: ```c Enqueue(Q,item) { rear = (rear+1)%n; if(rear == front) then return "full"; else { item = Q[rear]; } } Dequeue(Q) { if(front == rear) then return "empty"; else { front = (front+1)%n; item = Q[front]; return item; } } ``` 法三: ```c Enqueue(Q,item) { if(rear == front)and(Tag==True)then return "Q滿" else { rear = (rear+1)%n; Q[rear] = item; if(rear == front) then Tag = True; } } Dequeue(Q) { if(rear == front)and(Tag==False)then return "Q空" else { front = (front+1)%n; item = Q[front]; if(rear == front) then Tag = False; return item; } } ``` <font color=red>front下的那一格不用,因此每次要pop都要先加一</font> 二、利用link list製作 * single link list ```c Enqueue(Q,item) { new(t); t -> data = item; if(Front == Nil) then Front = t; else { Rear->link = t; } Rear = t; } Dequeue(item) { if(front == Nil)then return "Q空"; else { t = Front; item = Front->Data; Front = Front->link; if(front == Nil) then Rear=Nil; Free(t); return item; } } ``` * circular link list(環狀串列)做Queue ```c Enqueue(Q,item) { new(t); t->Data = item; if(rear == Nil) then rear = t; else { t->link = rear->link; rear->link = t; } rear = t; } Dequeue(Q) { if(rear == Nil) then return "Q空"; else { if(rear->link == rear) { t = rear; item = rear->Data; rear = Nil; free(t); return item; } else { t = rear->link; item = (rear->link)->Data; rear->link = (rear->link)->link; free(t); return item; } } } ``` ### Queue的種類 * FIFO Queue * Priority Queue * Double-ended Queue * Double-ended priority Queue * 製作此Queue的最合適data structure有: [1]min-max heap [2]Deap [3]SMMH ## Stack與Queue之相互製作 一、使用stack製作Queue 做法:利用2個stacks:S與I ```c Enqueue(Q,item) { push(S,item); } Dequeue(item) { if(Isempty(T)then) if(Isempty(S))then return "Q空" else { while(NOT Isempty(S)) { x=pop(S); push(T,x); //全部在倒入另一個袋子裡 } } item=pop(T); return item; } ``` <font color=red>Enqueue Time:O(1)</font> Dequeue Time: 大部分情況(T不等於空)是O(1) 少部份情況(T等於空,S不等於空)是O(n) <font color=red>以amortized Time(cost)=>O(1)</font> 二、利用Queue做stack ```c push(s,item) { Enqueue(Q,item); } pop(s) { if(Isempty(Q)then return "S空"); else { n=Queue中元素個數; for i=1 to (n-1) do { x=Dequeue(Q); Enqueue(Q,x); } item=Dequeue(Q); return item; } } ``` 將queue中所有元素取出來重新加入=>爛方法 ## 額外queue問題 假設Queue是用circular Array製作(最多利用n-1格) 如何以front,rear,n表示Queue中元素個數? =><font color=red>(rear-front+n)%n</font> ###### tags: `data structure` `chp3` `stack` `queue`