C语言二叉树表达式求值——表达式二叉树的建立

如果需要c++的二叉树表达式求值,请参考这位作者ff608deb7a8b440a98b3d794971b365d.jpg

 根据其代码原理可转换为以下C语言代码

#include <stdio.h>
#include <malloc.h>
#include<string.h>
int  count=0;                   /*定义计算结点个数的变量*/
typedef  struct  tnode

   char  data;
   struct  tnode  *lchild,*rchild;
}BT;

BT *BuildTree(char m[],int x,int y){//表达式建立树
    /*此处表达式二叉树建立基本原理简述:
    找表达式根结点(即优先级较低的运算符),
    再以根结点位置拆分为左右表达式,左右再 
    反复找根结点,直到拆分为只剩下数字字符,
    即是叶子结点 。则表达式树成 
    */ 
    int c1=-1,c2=-1,p=0,i;//c1,c2来记录运算符位置 
    BT *q;//新结点
    q=(BT *)malloc(sizeof(BT));
    int num=0;//记录数字字符 
    for(i=x;i<y;i++){//记录数字字符个数 
        if(m[i]>='0'&&m[i]<='9')
        num++;
    }
    if(num==y-x){//递归停止部分 ,即叶子结点 
        ++count;
        q->data=m[x];
        q->lchild=NULL;
        q->rchild=NULL;
        return q;
    }    
    for    ( i=x;i<y;i++){//寻找根结点位置 
        switch(m[i]){ 
            case '(':p++;break;
            case ')':p--;break;
            /*p==0时,说明运算符在括号外,可以跳过括号,
            找到括号外的运算符优先级较低的位置分别用 
            c1,c2来记录 
             */ 
            case '+':case '-':if(p==0)c1=i;break; 
            case '*':case '/':if(p==0)c2=i;break;
        }
    }
    if(c1<0)c1=c2;//c1<0说明括号外没有+或-符号,令c1=c2,让c1始终代表优先级较低 
    if(c1<0){//c1<0再次出现说明,括号外再无运算符,则可以开始考虑括号里的内容 
        if(y-1>x+1)//判断括号里是否有字符再进行递归 
        return BuildTree(m,x+1,y-1);
        /*
        参数使用x+1,y-1,可以使在递归过程里达到去括号的"效果",
        即只需考虑括号里表达式,括号不会影响 
        */ 
    }
    count++;//记录结点数 
    q->data=m[c1];//存根结点 
    q->lchild=BuildTree(m,x,c1);//建立左子树 
    q->rchild=BuildTree(m,c1+1,y);//建立右子树 
    return q;
    
}
void  PreOrder(BT  *T)                      /* 先序遍历二叉树T*/
{   if(T==NULL)  return;                    /* 递归调用的结束条件*/
    else
    {  printf("%c",T->data);                /* 输出结点的数据域*/
       PreOrder(T->lchild);                 /* 先序递归遍历左子树*/
       PreOrder(T->rchild);                 /* 先序递归遍历右子树*/
    }
}
int main(){
    BT *T;
    int x=0,y;
    char a[20];
    while(true){
        
    printf("请输入表达式:");
    scanf("%s",&a) ;
    y=strlen(a);
    T=BuildTree(a,x,y);
    printf("先序遍历为:");
    PreOrder(T);
    printf("\n");    
    }
}

以下是运行截图

9d85f7c2e74a4b4a96d4365ce7d5ac03.jpg

 最后感谢原作者的分享,需要的小伙伴可以参考我转换后的C语言代码。

 

 

 

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
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; } } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值