C語言- 基礎資料結構和演算法 - 09 棧的應用_中綴表示式轉字尾表示式20220611

油膩老張 發表於 2022-06-11
演算法 資料結構

09 棧的應用_中綴表示式轉字尾表示式20220611

聽黑馬程式設計師教程《基礎資料結構和演算法 (C版本)》,

照著老師所講抄的,

視訊地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1

喜歡的朋友可以去看看,歡迎大家一起交流學習。

09 棧的應用_中綴表示式轉字尾表示式20220611_main.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "LinkStack.c"



typedef struct MYCHAR{
    LinkNode* node;
    char* pAddres;        // 放字元地址,因為每個字元都有一個地址。 
    int index;            // 記錄位置 
}MyChar;


// 判斷是否是數字 
int IsNumber(char c){
    return c >='0' && c <='9';
}

// 輸出數字
void NumberOperate(char* p){
    printf("%c",*p);
} 

// 判斷是否左括號和右括號 
int IsLeft(char c){
    return c == '(';
}
int IsRight(char c){
    return c == ')';
}

// 判斷是否運算子號
int IsOperator(char c){
    return c=='+' || c=='-' || c=='*' || c=='/';
}
// 返回運算子的優先順序
int GetPriority(char c){
    if(c=='*' || c == '/'){
        return 2;
    }
    if(c=='+'|| c=='-'){
        return 1;
    }
    return 0;
} 

// 建立MyChar
MyChar* CreateMyChar(char* p){
    MyChar* mychar = (MyChar*)malloc(sizeof(MyChar));
    mychar->pAddres = p;
    return mychar;
} 



// 左括號進棧
void LeftOperate(LinkStack* stack,char* p){
    Push_LinkStack(stack,(LinkNode*)CreateMyChar(p));
}

// 右括號操作 彈出並輸出,直到匹配左括號
void RightOperate(LinkStack* stack){
    // 先判斷棧中有沒有元素,有則彈,
    while(Size_LinkStack(stack)>0){
        MyChar* mychar = (MyChar*)Top_LinkStack(stack);
        // 如果匹配左括號,則出棧 
        if(IsLeft(*(mychar->pAddres))){
            Pop_LinkStack(stack);
            break;
        }
        // 不匹配左括號,則輸出,彈出 
        printf("%c",*(mychar->pAddres));
        Pop_LinkStack(stack);
        free(mychar);                
    }         
} 

// 運算子號的操作
void OperatorOperator(LinkStack* stack,char* p){
    // 先取出棧頂符號
    MyChar* mychar = (MyChar*)malloc(sizeof(MyChar));
    if(mychar==NULL){
        Push_LinkStack(stack,(LinkNode*)CreateMyChar(p));
        return;
    } 
    // 如果棧頂優先順序低於當前字元的優先順序,則直接入棧 
    if(GetPriority(*(mychar->pAddres))< GetPriority(*p)){
        Push_LinkStack(stack,(LinkNode*)CreateMyChar(p));
        return;
    }
    // 如果優先順序不低, 
    else{
        while(Size_LinkStack(stack) > 0){
            MyChar* mychar2 = (MyChar*)malloc(sizeof(MyChar));
            // 如果優先順序低,當前符號入棧 
            if(GetPriority(*(mychar2->pAddres))<GetPriority(*p)){
                Push_LinkStack(stack,(LinkNode*)CreateMyChar(p));
                break;                
            }
            // 輸出 
            printf("%c",*(mychar2->pAddres));
            // 彈出
            Pop_LinkStack(stack); 
            // 釋放
            free(mychar2); 
            
        } 
        
        
    }
     
} 

int main(){
    printf("好好學習,天天向上~!\t\t\t 09_棧的應用_中綴表示式轉字尾表示式20220611\n\n\n");
    
    char* str ="8+(3-1)*5";    
    char* p = str;
    
    // 建立棧
    LinkStack* stack = Init_LinkStack();
     
    while(*p !='\0'){
        // 如果是數字,直接輸出 
        if(IsNumber(*p)){
            // 直接輸出
            NumberOperate(p);
        }
        
        // 如果是左括號,進棧
        if(IsLeft(*p)){
            LeftOperate(stack,p);
        } 
        
        // 如果是右括號,則將棧頂符號彈出並輸出,直到匹配左括號
        if(IsRight(*p)){
            RightOperate(stack);
        } 
        
        // 如果是運算子號
        if(IsOperator(*p)){
            OperatorOperator(stack,p);
        }
            
        p++;
    }
    
    while(Size_LinkStack(stack)>0){
        
        MyChar* mychar = (MyChar*)Top_LinkStack(stack);
        printf("%c",*(mychar->pAddres));
        Pop_LinkStack(stack);
        free(mychar);
        
    }
    // 以上輸出結果為  831-5*+ 
    printf("\n\n");
    system("pause");
    return 0;
}

LinkStack.c

 1 #ifndef LINKSTACK_H
 2 #define LINKSTACK_H
 3 
 4 #include <stdio.h>
 5 #include <stdlib.h>
 6 
 7 
 8 // 鏈式棧的節點 
 9 typedef struct LINKNODE{
10     struct LINKNODE* next; 
11 }LinkNode;
12 
13 // 鏈式棧 
14  
15 typedef struct LINKSTACK{
16     LinkNode HeadNode;    //頭節點
17     int size;
18 }LinkStack; 
19 
20 // 初始化
21 LinkStack* Init_LinkStack();
22 // 入棧
23 void Push_LinkStack(LinkStack* stack,LinkNode* data);
24 // 出棧 (刪除第一個元素) 
25 void Pop_LinkStack(LinkStack* stack); 
26 // 返回棧頂元素
27 LinkNode* Top_LinkStack(LinkStack* stack); 
28 // 返回棧元素的個數
29 int Size_LinkStack(LinkStack* stack); 
30 // 清空棧
31 void Clear_LinkStack(LinkStack* stack);
32 // 銷燬棧
33 void FreeSpace_LinkStack(LinkStack* stack); 
34 
35 
36 
37 #endif

LinkStack.h

 1 #include "LinkStack.h"
 2 
 3 
 4 // 初始化
 5 LinkStack* Init_LinkStack(){
 6     
 7     // 開記憶體
 8      LinkStack* stack = (LinkStack*)malloc(sizeof(LinkStack));
 9      // 初始化
10      stack->HeadNode.next = NULL;
11      stack->size = 0;
12     
13     return stack;
14 }
15 
16 // 入棧
17 void Push_LinkStack(LinkStack* stack,LinkNode* data){
18     
19     if(stack == NULL){
20         return;
21     }
22     if(data == NULL){
23         return;
24     }
25     
26     data->next = stack->HeadNode.next;
27     stack->HeadNode.next = data;
28     
29     stack->size++;
30     
31 }
32 
33 // 出棧 (刪除第一個元素) 
34 void Pop_LinkStack(LinkStack* stack){
35     
36     if(stack == NULL){
37         return ;
38     }
39     if(stack->size==0){
40         return ;
41     }    
42     
43     // 第一個有效節點
44     LinkNode* pNext =  stack->HeadNode.next;
45     stack->HeadNode.next = pNext->next;    // pNext.next為第一個有效節點的下一個節點 
46     
47     stack->size--;
48 
49 }
50 
51 // 返回棧頂元素
52 LinkNode* Top_LinkStack(LinkStack* stack){
53     
54     if(stack == NULL){
55         return NULL;
56     }
57     if(stack->size==0){
58         return NULL;
59     }            
60     
61     return stack->HeadNode.next;
62 }
63 
64 // 返回棧元素的個數
65 int Size_LinkStack(LinkStack* stack){
66     if(stack == NULL){
67         return -1;
68     }    
69     return stack->size;
70 }
71 
72 // 清空棧
73 void Clear_LinkStack(LinkStack* stack){
74     
75     if(stack == NULL){
76         return;
77     }
78     stack->HeadNode.next = NULL;
79     stack->size=0;    
80     
81 }
82 
83 // 銷燬棧
84 void FreeSpace_LinkStack(LinkStack* stack){
85     
86     if(stack == NULL){
87         return;
88     }
89     
90     free(stack);
91     
92     
93 }

 

相關文章