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 }