数据结构作业--计算器(用中缀表达式实现表达式树)

Tree.h

#ifndef TREE_H_INCLUDED
#define TREE_H_INCLUDED
#include <iostream>
#include "stdlib.h"
#include "stack"
#include <vector>

using namespace std;
//定义节点结构
typedef struct Node
{
        char data;
        struct Node *lchild;
        struct Node *rchild;
}Node;
//存放节点的栈
stack<Node*> numberStack;
//存放运算符的栈
stack<char> operatorStack;

Node * ExpressionTree(){
    //用户输入的表达式放入exp
    string exp;
    cout << "请输入中缀表达式:";
    cin >> exp;

    Node *node;
    for(int i = 0 ; i < exp.length() ; i++){
        //如果为运算数将其封装成一个节点压入栈中
        if(exp[i] - '0' >= 0 && exp[i] - '0' <= 9){
            node = new Node;
            node->data = exp[i];
            node->lchild = NULL;
            node->rchild = NULL;

            numberStack.push(node);
        }
        //如果为运算符
        else if(exp[i] == '+' || exp[i] == '-' || exp[i] == '*' || exp[i] == '/'){
            //如果新的运算符优先级不大于栈顶的,'+' '-' 优先级肯定不大于栈顶运算符,
            //运算符栈顶为'*' '/'不管新运算符是什么优先级都不会大于它,直接出栈
            if(!operatorStack.empty()&&(exp[i] == '+' || exp[i] == '-' || operatorStack.top() == '*' || operatorStack.top() == '/') ){
                //将运算符栈顶元素封装为节点
                node = new Node;
                node->data = operatorStack.top();
                operatorStack.pop();
                //令运算符左右子树为运算数栈前两个
                node->rchild = numberStack.top();
                numberStack.pop();
                node->lchild = numberStack.top();
                numberStack.pop();
                //将节点放入栈,等于把两个运算数结合运算符成为一个节点了
                numberStack.push(node);
                //将新运算符放入
                operatorStack.push(exp[i]);
            }
            //新运算符优先级高直接入栈
            else {
                operatorStack.push(exp[i]);
            }

        }

    }

    //将运算符和运算数栈所有元素出栈做结合再放入运算数栈
    while(!operatorStack.empty()){
        node = new Node;
        node->data = operatorStack.top();
        operatorStack.pop();
        node->rchild = numberStack.top();
        numberStack.pop();
        node->lchild = numberStack.top();
        numberStack.pop();

        numberStack.push(node);
    }
    //此时运算数栈只有一个节点元素便是root节点
    return numberStack.top();

}


//前期用于测试树的创建和前中后续遍历的是否正确无关本题
void CreateTree(Node **T)
{
    char ch ;
    cin >> ch ;
    *T = new Node;
    if(ch == '0')
    {
        *T = NULL;
        return;
    }
    else
    {
        (*T)->data = ch;
        cout << (*T)->data << "的左子树为" << endl;
        CreateTree(&((*T)->lchild));
        cout << (*T)->data << "的右子树为" << endl;
        CreateTree(&((*T)->rchild));
    }
}

//前序遍历打印树
void PreOrder(const Node * T)
{
    if(T != NULL)
    {
        cout << T->data;
        PreOrder(T->lchild);
        PreOrder(T->rchild);

    }
}
//中序遍历打印树
void InOrder(const Node *T)
{
    if(T != NULL)
    {
       InOrder(T->lchild);
        cout << T->data;
       InOrder(T->rchild);
    }
}
//后序遍历将此序列的元素放入str容器中,传回给主函数
void PostOrder(const Node *T , vector<char> &str)
{
    if(T != NULL)
    {
        PostOrder(T->lchild , str);
        PostOrder(T->rchild , str);
        str.push_back(T->data);
    }

}



#endif // TREE_H_INCLUDED

#include <iostream>
#include "Tree.h"
#include <vector>
/*此程序由于时间问题暂未实现加括号操作且只适用于int数据
    还有一些边界值的异常处理没完成,待续。。。
*/

using namespace std;

int Caculate(vector<char> str);

int main()
{
    Node * T = ExpressionTree();
    vector<char> str;

    PostOrder(T , str);
    int result = Caculate(str);

    cout << "前缀表达式为:";
    PreOrder(T);
    cout << endl;

    cout << "后缀表达式为:";
    for(int i = 0 ; i < str.size() ; i++){
        cout << str[i];
    }
    cout << endl;

    cout << "运算结果为:" << result << endl;

}

//利用后缀表达式计算返回结果
//定义一个栈用于装每次运算完的结果
stack<int> intStack;

int Caculate(vector<char> str){
    for(int i = 0 ; i < str.size() ; i++){
        int a , b ;
        //运算数就压入栈
        if(str[i] - '0' >= 0 && str[i] - '0' <= 9){
            intStack.push(str[i] - '0');
        }
        //运算符就执行运算
        else{
            switch(str[i]){
            case '+' :
            a = intStack.top();
            intStack.pop();
            b = intStack.top();
            intStack.pop();

            intStack.push(b + a);
            break;

            case '-' :
            a = intStack.top();
            intStack.pop();
            b = intStack.top();
            intStack.pop();

            intStack.push(b - a);
            break;

            case '*' :
            a = intStack.top();
            intStack.pop();
            b = intStack.top();
            intStack.pop();

            intStack.push(b * a);
            break;

            case '/' :
            a = intStack.top();
            intStack.pop();
            b = intStack.top();
            intStack.pop();

            intStack.push(b / a);
            break;
            }
        }
    }
    return intStack.top();
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值