利用递归和二叉树实现多位数整数的计算

 题目:


 功能设计:

  1. 读取用户输入的表达式创建表达式树功能
  2. 遍历表达式树进行表达式求值功能
  3. 输出表达式计算结果功能

功能实现: 

1. 

2.

3.


运行结果: 

用户输入1,输入要计算的表达式并以#结尾,系统便会给出计算结果。

用户输入2,退出程序。


 完整代码展示:

#include<iostream>
using namespace std;
//二叉树结构
typedef struct BiTNode
{
    char data;
    int   num;
    struct BiTNode* lchild, * rchild;
}BiTNode, * BiTree;

//栈结构
typedef struct StackNode
{
    BiTNode* root;
    char   op;
    struct StackNode* next;
} StackNode, * LinkStack;

int InitStack(LinkStack& S)  //构造空栈
{
    S = NULL;
    return 1;
}

int Push_root(LinkStack& S, BiTree e)      //根节点入栈
{
    LinkStack p = new StackNode;
    if (!p)
        exit(OVERFLOW);
    p->root = e;
    p->next = S;
    S = p;
    return 1;
}

void Push_op(LinkStack& S, char e)      //操作符入栈

{
    LinkStack p = new StackNode;
    if (!p)
        exit(OVERFLOW);
    p->op = e;
    p->next = S;
    S = p;
}

int Pop_root(LinkStack& S, BiTree& e)  //根节点出栈
{
    if (S == NULL)
    {
        cout << "输入格式错误,请输入整数表达式";
        return 0;
    }
    e = S->root;
    LinkStack p = S;
    S = S->next;
    delete p;
    return 1;
}

int Pop_op(LinkStack& S, char& e)  //操作符出栈
{
    if (S == NULL)
    {
        cout << "输入格式错误,请输入整数表达式";
        return 0;
    }
    e = S->op;
    LinkStack p = S;
    S = S->next;
    delete p;
    return 1;
}

char  GetTop_op(LinkStack S)    //返回栈顶元素
{
    if (S != NULL)     //栈非空
        return S->op;
}

char Precede(char t1, char t2)  //判断两个运算符的优先关系
{
    char f{};
    switch (t2)
    {
    case '+':
        if ((t1 == '(') || (t1 == '#'))
            f = '<';
        else f = '>';
        break;
    case '-':
        if ((t1 == '(') || (t1 == '#'))
            f = '<';
        else f = '>';
        break;
    case '*':
        if ((t1 == '*') || (t1 == '/') || (t1 == ')'))
            f = '>';
        else f = '<';
        break;
    case '/':
        if ((t1 == '*') || (t1 == '/') || (t1 == ')'))
            f = '>';
        else f = '<';
        break;
    case '(':
        f = '<';
        break;
    case ')':
        if ((t1 == '('))
            f = '=';
        else f = '>';
        break;
    case '#':
        if (t1 == '#')
            f = '=';
        else f = '>';
        break;
    }
    return f;
}

int In(char i)  //判断读取到的字符是否是操作符
{
    switch (i)
    {
    case '+': case '-':  case '*':  case '/':
    case '(':   case ')':  case '#':  return 1;
        break;
    default:  return 0;
    }
}

int  GetValue(int a, char theta, int b)
{
    switch (theta)
    {
    case '+': return a + b;
    case '-': return a - b;
    case '*': return a * b;
    case '/': return a / b;
    }
}

void CreateExpressTree_op(BiTree& T, BiTree a, BiTree b, char theta)
//创建一棵树,左孩子是a,右孩子是b,数据域是theta用来储存运算符
{
    BiTree L = new BiTNode;
    L->data = theta;
    L->lchild = a;
    L->rchild = b;
    T = L;
}

void CreateExpressTree_num(BiTree& T, BiTree a, BiTree b, int theta)
//创建一棵树,左孩子是a,右孩子是b,数据域是theta用来储存数字
{
    BiTree L = new BiTNode;
    L->num = theta;
    L->lchild = a;
    L->rchild = b;
    T = L;
}

void CreateBiTree(BiTree& T)  //读取输入表达式创建二叉树
{
    LinkStack EXPT;
    LinkStack OPTR;
    InitStack(EXPT);
    InitStack(OPTR);
    Push_op(OPTR, '#');
    BiTree a = NULL, b = NULL, c, d;
    char ch, theta, f;
    int m = 0;
    cin >> ch;
    while ((ch != '#') || (GetTop_op(OPTR)) != '#')
    {
        if (!In(ch))   //判断读取到的字符是不是运算符
        {             //当字符是数字时
            while (!In(ch))
            {
                //实现多位整数
                ch = ch - '0';
                m = m * 10 + ch;
                ch = getchar();
            }
            if (m != 0)
            {
                CreateExpressTree_num(T, a, b, m); //以m为节点创建一棵只有根节点的二叉树
                Push_root(EXPT, T);                //将二叉树根节点T进EXPT栈
                m = 0;
            }
        }
        else   //读取到的字符是四则运算符
        {
            switch (Precede(GetTop_op(OPTR), ch))    //判断优先级
            {
            case '<': Push_op(OPTR, ch);             //当前字符压入OPTR栈,读取下一字符
                ch = getchar();
                break;
            case '>': Pop_op(OPTR, theta);           //弹出OPTR栈顶的运算符
                Pop_root(EXPT, c);                   //弹出EXPT栈顶的两个操作数
                Pop_root(EXPT, d);
                CreateExpressTree_op(T, d, c, theta);//以theta为根,d为左子树,d为右子树,创建一棵二叉树
                Push_root(EXPT, T);                  //使二叉树根节点进EXPT栈
                break;

            case '=':
                Pop_op(OPTR, f);
                ch = getchar();
                break;
            }
        }
    }
}


int EvaluateExPTree(BiTree T) //遍历表达式数进行表达式求值

{
    int lvalue = 0, rvalue = 0;//初始值为0
    if (T->lchild == NULL && T->rchild == NULL)
        //如果节点为操作数,则返回该结点的数值
    {
        return T->num;
    }
    else
    {
        lvalue = EvaluateExPTree(T->lchild);
        //递归计算左子树的值
        rvalue = EvaluateExPTree(T->rchild);
        //递归计算右子树的值
        return GetValue(lvalue, T->data, rvalue);
        //根据当前节点运算符的类型进行相应运算
    }
}

int main()
{
    while (true) {
        cout << "******************************************" << endl;
        cout << "**                                      **" << endl;
        cout << "**-----------欢迎来到表达式计算*--------**" << endl;
        cout << "**                                      **" << endl;
        cout << "**   1.输入整数表达式(以#结尾):      **" << endl;
        cout << "**                                      **" << endl;
        cout << "**   2.退出                             **" << endl;
        cout << "**                                      **" << endl;
        cout << "******************************************" << endl;
        int op;
        cout << "请输入你的选择:";
        cin >> op;
        BiTree T;
        switch (op) {
        case 1:
            cout << "请输入整数表达式(以#结尾):" << endl;
            CreateBiTree(T);   //创建表达式二叉树函数
            cout << "计算结果为:" << EvaluateExPTree(T) << endl;
            break;
        case 2:
            exit(0);
            break;
        }
    }
    return 0;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值