栈应用:中缀表达式转后缀表达式并以二叉树储存

本文介绍了如何将中缀表达式转换为后缀表达式,利用栈的数据结构进行处理,并详细说明了转换过程中运算符优先级的判断规则。此外,还探讨了如何通过后缀表达式构建二叉树并进行计算,以及如何进行后序遍历来计算节点值。同时,提到了去括号的问题,通过中序遍历二叉树来处理括号的添加。
摘要由CSDN通过智能技术生成

中缀表达式就是我们平时所看到的一般计算表达式,如:
①最简单的: 1 + 1
②稍微复杂一点的: 8 – ( 3 + 2 * 6 ) / 5 + 4

而后缀表达式(也被称为逆波兰式)则是将运算符放在了最后,两个操作数放在前面,以及不需要括号表示运算的优先级, 如:
①1 + 1 对应的就是 1 1 +
②8 – ( 3 + 2 * 6 ) / 5 + 4 对应的就是 8 3 2 6 * + 5 / – 4 +

详细逆波兰式的定义请参考百度百科
http://baike.baidu.com/link?url=7RYiuxHeWH7ikiVkP6s7RxwBrowWemzp_yL9MkqsBMd0Q3KAFB_35XexPBsq6g-ZvRoHE6MpQIaCzNbyMnI6Qq
OJ题可参考
http://codevs.cn/problem/2471/

现在当我们输入一个中缀表达式(不能有负数输入)的时候,我们通过两个栈来得到后缀表达式,这里我采用链表来实现栈,当然你也可以使用数组(更节省空间)。

typedef struct Node {
    char element;    //储存操作数或者运算符
    struct Node *prev;
    struct Node *next;
}Node;
typedef struct {
    Node *top;
    Node *base;
}Stack;

//以及栈的一些基本操作

//初始化栈,栈底设头结点,并以'#'为栈底标志
Stack *IntiStack(){
    Stack *result = (Stack *)malloc(sizeof(Stack));
    Node *headNode = (Node *)malloc(sizeof(Node));
    headNode->prev = NULL;
    headNode->next = NULL;
    headNode->element = '#';
    result->top = headNode;
    result->base = headNode;
    return result;
}

//将一个操作数或者运算符推进栈中
void Push(Stack *result, char element){
    Node *newNode = (Node *)malloc(sizeof(Node));
    newNode->element = element;
    newNode->prev = result->top;
    newNode->next = NULL;
    result->top->next = newNode;
    result->top = newNode;
}

//获得栈中顶元素的值
char getTop(Stack *result){
    return result->top->element;
}

//将栈中顶元素的值弹出,除非栈为空
char Pop(Stack *result){
    char temp;
    if(result->top != result->base){
        temp = result->top->element;
        result->top = result->top->prev;
        result->top->next = NULL;
        return temp;
    }
    return '#';
}

首先第一个栈temp是一个临时栈,负责储存运算符,并且该栈的头元素优先级最高(即从底到头优先级递增), 第二个栈result是结果栈, 从底到头储存了一个完整的后缀表达式。

中缀表达式转换为后缀表达式最为重要的就是当我碰到一个操作数或者运算符的时候应该怎么处理, 也就是优先级的确认。
①遇到操作数的时候直接推进result
②遇到运算符的时候需要比较该运算符与temp栈头元素的运算符的优先级,如果该运算符优先级高于(不包括等于)则将运算符推进temp, 否则弹出temp栈的头元素直到头元素的优先级低于该运算符,最后将该运算符推进temp中。
③当然有特殊情况,也就是遇到左括号“(”的时候直接推进temp, 当其他运算符与左括号比较优先级的时候可认为左括号的优先级最低。遇到右括号的时候,不断弹出栈的头元素直到遇到左括号,左括号弹出后不入result(后缀表达式不需要括号)
④接下来我们详细讨论每种情况:
“+”:优先级是最低的,几乎所有运算符都要弹出(包括加号自身),除了左括号。
“-”:与加号优先级相同,同上。
“*”:优先级稍高,只有遇到乘号,除号,以及幂号的时候才需要弹出。
“/”:与乘号优先级相同,同上。
“^”:优先级最高

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值