利用二叉树求表达式的值,首先要注意表达式中先乘除后加减的运算顺序,所以在建立树的过程中,就要将加减尽量作为根节点,最后一个加减号作为根节点。建完树之后是运算过程,采用树的后序遍历来运算。

二叉树的节点结构,其中值的类型用char型

struct node
{
    char data;
    node* left;
    node* right;
};
node *CRTree(char s[],int begin,int end)
{
    node *p;
    int k,plus=0,posi;
    if (begin==end)    //只有一个字符,构造的是一个叶子节点
    {
        p=(node *)malloc(sizeof(node));   //分配存储空间
        p->data=s[begin];                         //值为s[begin]
        p->left=NULL;
        p->right=NULL;
        return p;
    }
    //以下为begin!=end的情况
    for (k=begin; k<=end; k++)
        if (s[k]=='+' || s[k]=='-')
        {
            plus++;
            posi=k;              //最后一个+或-的位置
        }
    if (plus==0)                 //没有+或-的情况(因为若有+、-,前面必会执行plus++)
        for (k=begin; k<=end; k++)
            if (s[k]=='*' || s[k]=='/')
            {
                plus++;
                posi=k;
            }
    //以上的处理考虑了优先将+、-放到二叉树较高的层次上
    //由于将来计算时,运用的是后序遍历的思路
    //处于较低层的乘除会优先运算
    //从而体现了“先乘除后加减”的运算法则
    //创建一个分支节点,用检测到的运算符作为节点值
    if (plus!=0)
    {
        p=(node *)malloc(sizeof(node));
        p->data=s[posi];                //节点值是s[posi]
        p->left=CRTree(s,begin,posi-1);   //左子树由s[begin]至s[posi-1]构成
        p->right=CRTree(s,posi+1,end);   //右子树由s[posi+1]到s[end]构成
        return p;
    }
    else       //若没有任何运算符,返回NULL
        return NULL;
}

下面是运算过程

double Comp(node *b)
{
    double v1,v2;
    if (b==NULL)
        return 0;
    if (b->left==NULL && b->right==NULL)  //叶子节点,应该是一个数字字符(本项目未考虑非法表达式)
        return b->data-'0';    //叶子节点直接返回节点值,结点中保存的数字用的是字符形式,所以要-'0'
    v1=Comp(b->left); //先计算左子树
    v2=Comp(b->right); //再计算右子树
    switch(b->data)     //将左、右子树运算的结果再进行运算,运用的是后序遍历的思路
    {
    case '+':
        return v1+v2;
    case '-':
        return v1-v2;
    case '*':
        return v1*v2;
    case '/':
        if (v2!=0)
            return v1/v2;
        else
            abort();
    }
}

最后要记得将新建的二叉树销毁

void DestroyBTNode(node *&b)   //销毁二叉树
{
    if (b!=NULL)
    {
        DestroyBTNode(b->left);
        DestroyBTNode(b->right);
        free(b);
    }
}

 

posted on 2018-08-22 15:51  Mini_Coconut  阅读(3875)  评论(0编辑  收藏  举报