22栈的应用-中缀表达式转后缀表达式

Posted luanxin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了22栈的应用-中缀表达式转后缀表达式相关的知识,希望对你有一定的参考价值。

main.c

#define _CRT_SECURE_NO_WARNING

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

//判断是不是数字
int IsNumber(char c) {
    return c >= 0 && c <= 9;
}

//判断是不是左括号
int IsLeft(char c) {
    return c == (;
}

//判断是不是右括号
int IsRight(char c) {
    return c == );
}

//判断是不是运算符号
int IsOperate(char c) {
    return c == + || c == - || c == * || c == /;
}

//返回运算符号优先级
int GetPriority(char c) {
    if (c == * || c == /) {
        return 2;
    }
    if (c == + || c == -) {
        return 1;
    }
    return 0;
}

typedef struct MYCHAR {
    StackNode node;
    char* p;
}MyChar;

//数字操作
void NumberOperate(char* p) {
    printf("%c", *p);
}

//创建MyChar
MyChar* CreatMyChar(char* p) {
    MyChar* mychar = (MyChar*)malloc(sizeof(MyChar));
    mychar->p = p;
    return mychar;
}

//左括号操作
void LeftOperate(LinkStack* stack,char* p) {
    Push(stack, (StackNode*)CreatMyChar(p));
}

//右括号操作
void RightOperate(LinkStack* stack) {
    //先判断栈中有没有元素
    while (StackLength(stack) > 0) {
        MyChar* mychar = (MyChar*)GetTop(stack);
        //如果匹配到左括号,弹出并输出
        if (IsLeft(*(mychar->p))) {
            Pop(stack);
            break;
        }

        //输出
        printf("%c", *(mychar->p));
        //弹出
        Pop(stack);
        //释放内存
        free(mychar);
    }
}

//运算符号的操作
void OperateOperate(LinkStack* stack, char* p) {

    //先取出栈顶符号
    MyChar* mychar = (MyChar*)GetTop(stack);
    if (mychar == NULL) {
        Push(stack, (StackNode*)CreatMyChar(p));
        return;
    }
    //如果栈顶符号优先级低于当前字符的优先级 直接入栈
    if (GetPriority(*(mychar->p)) < GetPriority(*p)) {
        Push(stack, (StackNode*)CreatMyChar(p));
        return;
    }

    //如果栈顶符号优先级不低
    else {
        while (StackLength(stack) > 0) {

            MyChar* mychar2 = (MyChar*)GetTop(stack);


            //如果优先级低 当前符号入栈
            if (GetPriority(*(mychar2->p)) < GetPriority(*p)) {
                Push(stack, (StackNode*)CreatMyChar(p));
                return;
            }

            //输出
            printf("%c",*(mychar2->p));
            //弹出
            Pop(stack);
            //释放
            free(mychar2);
        }
    }
}

int main() {

    char* str = "8+(3-1)*5";//831-5*+
    char* p = str;

    //创建栈
    LinkStack* stack = InitStack();


    while (*p != ) {

        if (IsNumber(*p)) {
            NumberOperate(p);
        }
        //如果是左括号,直接进栈
        else if (IsLeft(*p)) {
            LeftOperate(stack, p);
        }

        //如果是右括号
        else if (IsRight(*p)) {
            RightOperate(stack);
        }

        //如果是运算符号
        else if (IsOperate(*p)) {
            OperateOperate(stack, p);
        }

        p++;
    }

    while (StackLength(stack)>0) {
        MyChar* mychar = (MyChar*)GetTop(stack);
        printf("%c", *(mychar->p));
        Pop(stack);
        free(mychar);
    }


    printf("
");
    system("pause");
    return 0;
}

stack.h

#ifndef STACK_H
#define STACK_H

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

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

typedef void* SElemType;
typedef int Status;
//初始化结构
typedef struct StackNode {
    SElemType data;
    struct StackNode* next;
}StackNode, *LinkStackPtr;

typedef struct LinkStack {
    StackNode* top;
    int count;
}LinkStack;


//初始化操作,建立一个空栈
LinkStack* InitStack();
//将栈清空
void ClearStack(LinkStack *s);
//销毁
void DestoryStack(LinkStack *s);
//若栈为空,返回TRUE,否则返回false
Status IsEmpty(LinkStack s);
//若栈存在且非空,返回S的栈顶元素
void* GetTop(LinkStack *s);
//插入元素e为新的栈顶元素
Status Push(LinkStack *s, SElemType e);
//若栈不空,则删除S的栈顶元素,并返回OK,否则返回ERROR
Status Pop(LinkStack *s);
//返回栈S的元素个数
Status StackLength(LinkStack *s);

//打印
void PrintfStack(LinkStack *s);

#endif

stack.c

#include"Stack.h"

//初始化操作,建立一个空栈
LinkStack* InitStack() {
    LinkStack *s = (LinkStack*)malloc(sizeof(LinkStack));
    s->count = 0;
    s->top = (StackNode*)malloc(sizeof(StackNode));
    s->top->data = NULL;
    s->top->next = NULL;
    return s;
}
//将栈清空
void ClearStack(LinkStack *s) {


}
//销毁
void DestoryStack(LinkStack *s) {
    if (s == NULL) {
        return;
    }
    LinkStackPtr p;
    p = s->top;//将栈顶结点赋值给p
    while (p != NULL) {
        LinkStackPtr pNext = p->next;
        free(p);//释放结点p
        p = pNext;
    }
    s->count = 0;
    free(s);
}
//若栈为空,返回TRUE,否则返回false
Status IsEmpty(LinkStack s) {
    if (s.top->next == NULL) {
        return TRUE;
    }
    return FALSE;
}
//若栈存在且非空,返回S的栈顶元素
void* GetTop(LinkStack *s) {
    if (s == NULL) {
        return NULL;
    }

    return s->top->data;
}
//插入元素e为新的栈顶元素
Status Push(LinkStack *s, SElemType e) {
    LinkStackPtr a = (LinkStackPtr)malloc(sizeof(StackNode));
    a->data = e;
    a->next = s->top;//把当前的栈顶元素赋给新结点的直接后继
    s->top = a;//将新结点a赋值给栈顶指针
    s->count++;
    return OK;
}
//若栈不空,则删除S的栈顶元素,并返回OK,否则返回ERROR
Status Pop(LinkStack *s) {
    StackNode* p;
    if (IsEmpty(*s)) {
        return ERROR;
    }
    p = s->top;//将栈顶结点赋值给p

    s->top = p->next;//使得栈顶指针下移一位,指向后一结点
    free(p);//释放结点p

    s->count--;
    return OK;
}
//返回栈S的元素个数
Status StackLength(LinkStack *s) {

    int j = s->count;
    return j;
}

 

以上是关于22栈的应用-中缀表达式转后缀表达式的主要内容,如果未能解决你的问题,请参考以下文章

python数据结构 栈的实例 表达式转换 中缀转前缀后缀

栈的应用---中缀变后缀

中缀表达式转换成后缀表达式并求值

中缀表达式如何转换为前后缀表达式?

栈的应用之中缀表达式转化为后缀表达式(逆波兰表达式)

王道3.3 栈的应用以及队列的应用