表达式求值-二叉树实现

本来用栈实现表达式求值,这次用二叉树来实现,DRY


一开始做的时候,脑子里没有一点概念,而没概念是最要命的,所以在网上乱晃,希望有个解释,但可能实在太浮躁了,代码是不想看的,而思路自己也看不大懂,所以本来想TJ 最终忍住了,直接买了本数据结构(C语言版),慢慢看,它上面的思路很连续,看了之后终于懂了。


为了连续性,我先把后缀表达式的栈实现描述一下,因为栈实现对于计算过程的理解还是挺便利的。

我们平时计算的表达式是中缀表达式,(1+2)*3   => exp1

而后缀表达式是计算机非常喜欢的一种格式,将上面的expr1转换成后缀形式1 2 3 * +    => exp2

利用栈的先进后出原理, exp2的字符顺序压入栈,对于数字和操作符分别对待

如果exp2读取结束,退出

如果是数字,那就压入栈中

如果是操作符,弹出栈中适量数字,进行计算,再将计算结果压入栈


exp2为例,

step 1:

读取exp2  位置0字符‘1’ 压入栈中

栈底 1

step 2:

读取exp2  位置1字符‘2’ 压入栈中

栈底  1  2

step 3:

读取expr3 位置2字符‘3’ 压入栈中

栈底  1  2  3

step 4:

读取exp2  位置3字符 '*' 由于是运算符,并且它是二元运算符,所以弹出两个参数,即栈中的  23, 将它们相乘,把得到的值6压回栈中此时栈中由于弹出2次,压回一次,只剩下两个元素

栈底  1  6

step 5:

读取exp2  位置4字符 ’+', 由于是运算符,并且是二元运算符弹出两个参数, 即栈中的  16, 将结果7压回栈中, 此时栈中只剩下7一个元素

栈底  7

step  6:

  • 14
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
C语言二叉树表达式求值的具体步骤如下: 1. 定义二叉树节点结构体,包括节点值和左右子节点指针。 2. 定义一个函数用于创建表达式树,该函数接收一个表达式字符串作为参数,返回表达式树的根节点指针。 3. 定义一个函数用于遍历表达式树并计算表达式的值,该函数接收表达式树的根节点指针作为参数,返回表达式的值。 具体实现细节如下: 1. 定义二叉树节点结构体 ```c typedef struct TreeNode { char value; // 节点值 struct TreeNode *left; // 左子节点指针 struct TreeNode *right; // 右子节点指针 } TreeNode; ``` 2. 创建表达式树 ```c // 判断字符是否为运算符 int isOperator(char c) { return (c == '+' || c == '-' || c == '*' || c == '/'); } // 创建表达式树 TreeNode* createExpressionTree(char* expression) { int len = strlen(expression); TreeNode* stack[len]; // 定义栈 int top = -1; // 栈顶指针 for (int i = 0; i < len; i++) { char c = expression[i]; if (isOperator(c)) { // 如果是运算符 TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode)); // 创建新节点 node->value = c; node->right = stack[top--]; // 出栈并作为右子节点 node->left = stack[top--]; // 出栈并作为左子节点 stack[++top] = node; // 将新节点入栈 } else { // 如果是操作数 TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode)); // 创建新节点 node->value = c; node->left = NULL; node->right = NULL; stack[++top] = node; // 将新节点入栈 } } return stack[0]; // 栈中最后一个节点即为根节点 } ``` 3. 遍历表达式树并计算表达式的值 ```c // 计算表达式的值 int calculate(TreeNode* root) { if (root == NULL) { return 0; } if (root->left == NULL && root->right == NULL) { // 如果是叶子节点,返回节点值 return root->value - '0'; } int leftValue = calculate(root->left); // 递归计算左子树的值 int rightValue = calculate(root->right); // 递归计算右子树的值 switch (root->value) { // 根据运算符计算表达式的值 case '+': return leftValue + rightValue; case '-': return leftValue - rightValue; case '*': return leftValue * rightValue; case '/': return leftValue / rightValue; default: return 0; } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值