zoukankan      html  css  js  c++  java
  • 利用二叉树求表达式的值

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

    二叉树的节点结构,其中值的类型用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);
        }
    }
  • 相关阅读:
    二叉树的遍历
    深度优先遍历和广度优先遍历
    N的阶乘末尾有多少个0
    框架产生的历史
    Ansible--初始ansible
    日积跬步05
    日积跬步04
    日积跬步03
    日积跬步02
    日积跬步01
  • 原文地址:https://www.cnblogs.com/mini-coconut/p/9518192.html
Copyright © 2011-2022 走看看