虽然我的代码中正确给出了"括号处理"算法,但是我并没有启用那段代码,所以输入时请不要带括号
仅仅是因为个人不想做这个需求而已,"括号处理"代码经其他程序试验得证切实可行,如有疑问欢迎留言!
/*算法思想:
这个问题分为三部分:用栈把中序表达式转为后序表达式 由后序表达式递归建立二叉树 对已有的二叉树递归求解
第一部分:用栈把中序表达式转为后序表达式(Transform方法)
1.一个栈stack用于存储运算符,一个数组arr[]用于存储算术表达式,以及在后期存储后续表达式
2.从左向右开始读取算术表达式的元素X,分以下情况进行不同的处理:
(1) 如果X是操作数,直接依次从0位置开始覆盖arr[],因为原来位置上的数据要么在栈里,要么被刚刚拿出,可以大胆覆盖
(2) 如果X是运算符:再分以下情况:
1) 如果栈为空,直接入栈
2) 如果X=="(",直接入栈
3) 如果X==")",则将栈里的元素逐个出栈,并依次存入数组arr[]中,直到第一个配对的"("出栈
4) 如果X是其他操作符,则依次与栈顶元素比较优先级,如果栈顶元素的优先级大于等于X则出栈并按序存入数组arr[],直到栈顶元素的优先级小于X或者栈为空,再把元素X入栈,当已经没有元素可入栈,则依次出栈并按序存入数组arr[]
第二部分:由后序表达式递归建立二叉树(Insert方法)
1.对于每次插入操作都赋予一个success标记符,用于记录是否完成插入,当完成插入后,便可终止接下来的递归操作,毕竟已经插完了
2.我们注意到,其实每次插入时,都是在某个运算符节点的左孩子(右孩子)插入,而不是在数字节点插入,那我们就可以把递归的限制条件写为:非空&&不是数字节点&&本次插入标记符为0
3.对于后序遍历序列从右至左依次插入(其中最后一个节点默认为树的根节点)
每次插入遵循以下原则:
(1) 每次节点的试探顺序为:先右孩子 后左孩子
(2) 如果右孩子为空,直接插在右孩子的位置
如果右孩子不为空,则对右孩子进行递归
如果某运算符节点的右子树已经没有可以插入的合理位置,则对该运算符节点的左孩子进行递归
第三部分:对已有的二叉树递归求解(makeAll方法)
1.从根节点开始,先计算左子树,后计算右子树,在根据运算符节点的符号进行计算
其中左右子树均用递归计算
2.对于叶子节点(数字节点) 由于其没有左右孩子,直接返回自身数值即可
*
* */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MaxSize 100
int resultNum=0;
int result[100];
int queuenum=0;
struct Node *Tree=NULL;
struct Stack{ //定义栈
int data[MaxSize];
int top;
};
struct Node{ //定义树节点
int data;
struct Node *left;
struct Node *right;
};
void transFormNum(char temparr[]){
if(temparr[0]!='\0'){
switch (temparr[0]){
case 'a': result[resultNum++]=-1;brea