# 資結 第三章: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`