C语言基于链栈实现中缀表达式转后缀表达式

91 阅读2分钟

StackExpressionApply.h

#ifndef INC_3_6STACKQUEUEAPPLY_STACKEXPRESSIONAPPLY_H  
#define INC_3_6STACKQUEUEAPPLY_STACKEXPRESSIONAPPLY_H  
  
#include<stdio.h>  
#include<string.h>  
  
int GetOperationSymbolLever(char c);  
  
ElemType *MidToAfterExpression(char midExpression[]);  
  
    // 中缀表达式转换为后缀表达式  
    // todo 当表达式操作数值大于10如何处理? 暂时用0~9之间的数值实现  
    ElemType *MidToAfterExpression(char midExpression[]) {  
    // 初始化后缀表达式  
    ElemType *afterExpression = (ElemType*) malloc(sizeof (ElemType) * strlen(midExpression));  
    // 记录当前后缀表达式元素的下标  
    int index = 0;  
    // 初始化一个栈存储不确定运算顺序的运算符  
    LinkStack *stack = NULL;  
    for (int i = 0; i < strlen(midExpression); i++) {  
        char item = midExpression[i];  
        // 若为数字直接加入后缀表达式  
        if (item >= '0' && item <= '9') {  
            afterExpression[index] = item;  
            // 下标后移一位  
            index++;  
        } else if (item == '(') {  
            // 左括号直接入栈  
            Push(&stack, item);  
        } else if (item == ')') {  
            // )右括号依次出栈运算符直接匹配到左括号(  
            // 获取到一个栈顶元素  
            ElemType top;  
            Pop(&stack, &top);  
            while (top != '(') {  
            // 将运算符加入到后缀表达式  
            afterExpression[index] = top;  
            index++;  
            // top不为左括号就一直出栈  
            Pop(&stack, &top);  
            }  
        } else if (item == '+' || item == '-' || item == '*' || item == '/') {  
            ElemType top;  
            GetTop(stack, &top);  
            // 判断栈是否为空或栈顶元素为左括号 符合条件直接入栈  
            if (IsEmpty(stack) || top == '(') {  
            Push(&stack, item);  
        } else {  
            // 判断优先级 当前运算符大于栈顶元素的优先级则入栈  
            if (GetOperationSymbolLever(top) < GetOperationSymbolLever(item)) {  
            Push(&stack, item);  
            // 进入当前条件 就不指向下面的循环 进入下一次循环  
            continue;  
            }  
            // 否则依次出栈直到遇到优先级比它低的运算符或遇到左括号  
            while ((GetOperationSymbolLever(top) >= GetOperationSymbolLever(item) || 
            top != '(') &&  !IsEmpty(stack)) {  
                Pop(&stack, &top);  
                afterExpression[index] = top;  
                index++;  
            }  
                // 再将当前运算符入  
                Push(&stack, item);  
                }  
            } else {  
                // 字符不符合条件 终止函数运行 打印提示信息  
                printf("the input data is not allowed");  
                return NULL;  
            }  
        }  
        ElemType top;  
        // 最后将栈底元素依次出栈加入到后缀表达式  
        while (!IsEmpty(stack)) {  
        Pop(&stack, &top);  
        afterExpression[index] = top;  
        index++;  
}  
  
    return afterExpression;  
}  
  
// 获取运算符优先级  
int GetOperationSymbolLever(char c) {  
    if (c == '*' || c == '/') return 2;  
    return 1;  
}  
  
  
#endif //INC_3_6STACKQUEUEAPPLY_STACKEXPRESSIONAPPLY_H

LinkStack.c

#include<stdio.h>  
#include<stdlib.h>  
typedef char ElemType;  
  
typedef struct LinkStack {  
    ElemType data;  
    struct LinkStack *next;  
} LinkStack;  
  
int Push(LinkStack **L, ElemType e);  
  
int IsEmpty(LinkStack *L);  
  
int GetTop(LinkStack *L, ElemType *e);  
  
int Pop(LinkStack **L, ElemType *e);  
  
  
// 入栈  
// 注:必须使用二级指针 因为要修改指针变量的地址 用一级指针无法更改  
int Push(LinkStack **L, ElemType e) {  
  
// 新建节点  
LinkStack *s = (LinkStack *) malloc(sizeof(LinkStack));  
  
    // 入栈  
    s->next = *L;  
    s->data = e;  
    *L = s;  
    printf("%c进栈\n", e);  
    return 1;  
}  
  
// 判断是否为空  
int IsEmpty(LinkStack *L) {  
    if (L == NULL) return 1;  
    return 0;  
}  
  
  
// 返回栈顶元素  
int GetTop(LinkStack *L, ElemType *e) {  
    if (IsEmpty(L)) {  
    return -1;  
    }  
    // 取出栈顶元素`  
    *e = L->data;  
    return 1;  
}  
  
  
// 出栈  
// 注:必须使用二级指针 因为要修改指针变量的地址 用一级指针无法更改  
int Pop(LinkStack **L, ElemType *e) {  
    *e = (*L)->data;  
    *L = (*L)->next;  
    return 1;  
}  
  
  
// 销毁栈  
void DestroyStack(LinkStack **L) {  
    LinkStack *temp;  
    // 当头节点为NULL时 销毁结束  
    while ((*L) != NULL) {  
    temp = *L;  
    *L = (*L)->next;  
    free(temp);  
    }  
}

main.c

#include <stdio.h>  
#include "sources/StackExpressionApply.h"  
  
int main() {  
    char operations[] = "2+9*(3-4)-3/6+4*1";  
    char *expression;  
    expression = MidToAfterExpression(operations);  
    for (int i = 0; i < strlen(expression); ++i) {  
    printf("%c", expression[i]);  
    }  
    printf("\n");  
    return 0;  
}