1.1 - Stack
Introduction of Stack(堆疊的基本介紹及應用)
1. 介紹
堆疊(Stack)是一種特殊的抽象資料結構,可以用鏈結串列(Link List)或陣列(Array)來表示,堆疊的特點是只允許在Link List或是Array的頂端(Top)進行存取,具有先進後出(FILO, First-In-Last-Out)或後進先出(LIFO, Last-In-First-Out)的特性。

2. 基本操作
Pop(): 從堆疊的頂端(Top)取出資料。
Push(): 將資料放到堆疊的頂端。
IsEmpty(): 檢查是否堆疊為空。
IsFull(): 檢查堆疊是否已滿。(當使用Array製作堆疊時需注意是否已滿。)
2.1 以Link List來表示堆疊的基本操作。
Pop(): 回傳top指標(指向堆疊的頂端)的資料。
int pop(){
if (IsEmpty() == 1){ //檢查是否堆疊為空
printf("The stack is empty.\n");
return 0;
}
else{
stack *output = top;
top = top->next; //將top指向下一個node
return output->Data; //回傳頂端資料
}
return -1;
}
2. Push(data): 將資料放到堆疊的頂端。
void push(int data){
// 要求空間存取新資料
stack *new_node = (stack *)malloc(sizeof(stack));
// 將資料放到新的node中
new_node->Data = data;
new_node->next = NULL;
if (IsEmpty() == 1){ //如果堆疊為空,新放入的資料即為頂端
top = new_node;
}
else{
new_node->next = top; //原本的top變成舊的資料,所以將新node指向舊的資料(top)
top = new_node; //assign新的node為top
}
}
3. 輸出結果範例:
Push: 1, 2, 3
Stack: 3, 2, 1
Push: 4, 5
Stack: 5, 4, 3, 2, 1
Pop, the top is: 5
Pop, the top is: 4
Stack: 3, 2, 1
完整程式碼:https://github.com/gary30404/Data-Structure/blob/master/1/1.1/stack_in_linklist.c
2.2 以Array來表示堆疊的基本操作。和Link List不同的是,使用Array必須先宣告堆疊的大小,所以堆疊有可能會被填滿而無法再加入資料。
設定堆疊的大小
// define data type
typedef struct stack{
int *Data; // 陣列
int top; //頂端位置
int MAX_SIZE;
}stack;
2. Pop(): 回傳top指向堆疊的頂端的資料。
int pop(stack *st){
if (IsEmpty(st) == 1){
printf("The stack is empty.\n");
return 0;
}
else{
int output = st->Data[st->top];
st->Data[st->top] = 0; //設定為0代表此位置沒有存資料
st->top--; //top向下一層
return output;
}
return -1;
}
3. Push(data): 將資料放到堆疊的頂端。
void push(stack *st, int data){
if (IsFull(st) == 1){
printf("The stack is full.\n");
}
else{
st->Data[++st->top] = data; //先將top往上加一層後填入資料
}
}
4. 輸出結果範例:
Push: 1, 2, 3
Stack: 3, 2, 1
Push: 4, 5
Stack: 5, 4, 3, 2, 1
Pop, the top is: 5
Pop, the top is: 4
Stack: 3, 2, 1
完整程式碼:https://github.com/gary30404/Data-Structure/blob/master/1/1.1/stack_in_array.c
3. 應用(前、中、後序)
3.1 Infix(中序)
格式: operand1 operator
operand2
e.g. a+(b/c)
, x*y+z
缺點: 編譯器使用中序式做計算非常麻煩,因為必須要考慮運算子(operator)的優先順序和結合性,導致可能要來回掃描多次才能計算出結果。
3.2 Postfix(後序)
格式: operand1 operand2 operator
e.g. ab+
優點: 編譯器只需由左至右掃描一次即可球出結果,已免除掉運算子的優先順序和結合性。
3.3 Prefix(前序)
格式: operator
operand1 operand2
e.g. +ab
優點: 編譯器只需由右至左掃描一次即可球出結果,已免除掉運算子的優先順序和結合性。
4. 運算元之高低順序
括號()
負號-
^
*, /
+, -
>, <, ==, >=, ...
Logic
AND, OR
=
5. 轉換法則
將中序式轉成後(前)序式
在中序式加上完整的括號配對
將運算元取代最近的右(左)括號
刪去左(右)括號,其餘由左而右寫出即可得出後序式

中序轉後序演算法
由左至右掃描運算式
若遇到運算元則將其印出
若遇到運算子,考慮以下情況:
若stack為空,push()
若stack內有其他運算子,和頂端的運算子比較優先順序,stack頂端優先順序較小則push();stack頂端優先順序較大則pop(),直到stack頂端優先順序小於當前的運算子,或stack為空。
當遇到
)
時,pop()堆疊內的資料,直到(
。
掃完運算式後,將stack清空。
完整程式碼:https://github.com/gary30404/Data-Structure/blob/master/1/1.3/infix2postfix.c
後序法計算運算式演算法
將運算元push()到stack中,直到遇到運算子。
從stack中pop()出兩個運算元,並使用當前運算子做計算得出結果後在push()回stack中。
重複以上步驟,直到掃描完運算式。
Last updated