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製作堆疊時需注意是否已滿。)

  1. 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

  1. 設定堆疊的大小

// 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. 運算元之高低順序

  1. 括號()

  2. 負號-

  3. *, /

  4. +, -

  5. >, <, ==, >=, ...

  6. Logic

  7. AND, OR

  8. =

5. 轉換法則

  • 將中序式轉成後(前)序式

  1. 在中序式加上完整的括號配對

  2. 將運算元取代最近的右(左)括號

  3. 刪去左(右)括號,其餘由左而右寫出即可得出後序式

  • 中序轉後序演算法

  1. 由左至右掃描運算式

  2. 若遇到運算元則將其印出

  3. 若遇到運算子,考慮以下情況:

    1. 若stack為空,push()

    2. 若stack內有其他運算子,和頂端的運算子比較優先順序,stack頂端優先順序較小則push();stack頂端優先順序較大則pop(),直到stack頂端優先順序小於當前的運算子,或stack為空。

    3. 當遇到)時,pop()堆疊內的資料,直到(

  4. 掃完運算式後,將stack清空。

完整程式碼:https://github.com/gary30404/Data-Structure/blob/master/1/1.3/infix2postfix.c

  • 後序法計算運算式演算法

  1. 將運算元push()到stack中,直到遇到運算子。

  2. 從stack中pop()出兩個運算元,並使用當前運算子做計算得出結果後在push()回stack中。

  3. 重複以上步驟,直到掃描完運算式。

Last updated