【数据结构·树】二叉树:表达式二叉树转换成中缀式(括弧处理)(注意:运算符优先级以及与括号的结合性)C++

注意:

对于a+(b-c)可拆括号变成a+b-c,同样对于a*(b/c)可拆括号变成a*b/c;// + 与 *

而对于a-(b+c)不可拆括号变成a-b+c,同样对于a/(b*c)不可拆括号变成a/b*c。// - 与 /

问题描述

内容:(1)请参照链表的ADT模板,设计二叉树并逐步完善的抽象数据类型。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中。参考教材、课件,以及网盘中的链表ADT原型文件,自行设计二叉树的ADT。)

注意:二叉树ADT的基本操作的算法设计很多要用到递归的程序设计方法。

(2)ADT的简单应用:使用该ADT设计并实现若干应用二叉树的算法设计。

应用:要求设计一个算法,将表达式二叉树转换成原始的中缀表达式(括号恢复)。二叉树的存储结构的建立参见二叉树应用1。

注意:假定输入的中缀表达式为合法的表达式。仅考虑有小括弧的场合。运算符包括+、-、*、/,运算数为浮点数(可处理多位数、负数)。

参考函数原型:

(1)表达式二叉树转换成中缀式 (外壳部分,用户函数)

//表达式二叉树转换成中缀式

template<class ElemType>

void BianryTree_Infix(BinaryTree<ElemType> &T, string &inffix); //inffix:转换获得的中缀表达式字符串

(2)表达式二叉树转换成中缀式 (递归部分,用户函数)

//表达式二叉树转换中缀表达式 

template<class ElemType>

void BianryTree_Infix_Cursive(BinaryTreeNode<ElemType> *root, string &inffix);

辅助函数:

(1)判断是否为运算符(用户函数)

//判断是否为运算符  

bool isoperator( string op ){

if( op == "+" || op == "-" || op == "*" || op == "/" || op == "(" || op == ")" )

   return true;

return false;

}

(2)求运算符的优先级(用户函数)

//求运算符的优先级

int getOperPri(char op)  

{  

    switch(op)  

    {  

        case '(':  

        return 1; break;  

        case '+':  

        case '-':  

        return 2; break;  

        case '*':  

        case '/':  

        return 3; break;  

        default:  

        return 0;  

    }  

输入说明

第一行:表示无孩子或指针为空的特殊分隔符

第二行:二叉树的先序序列(结点元素之间以空格分隔)

输出说明

第一行:中缀表达式字符串(负数用一对小括号包含起来),字符串内无空格

输入范例

#
+ - + + -12.1 # # 14 # # 3 # # / 400 # # - 30 # # + 10 # # 5 # # 62.2 # #

输出范例

(-12.1)+14+3-400/(30-(10+5))+62.2

AC代码:

#include<iostream>
#include <sstream>
#include<string>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<stack>
#include<vector>
#include <climits>
#define MAX_SIZE 100
using namespace std;
bool sign;
//结点
template<class ElemType>
struct BinaryTreeNode
{
       ElemType data;
       BinaryTreeNode<ElemType> *LChild, *RChild;
       BinaryTreeNode() : LChild(NULL), RChild(NULL){}
       BinaryTreeNode(const ElemType &item, BinaryTreeNode<ElemType> *Lptr = NULL, BinaryTreeNode<ElemType> *Rptr = NULL)
       {
           LChild = Lptr;
           RChild = Rptr;
           data = item;
       }
};
//二叉树
template<class ElemType>
class BinaryTree
{
   private:
      BinaryTreeNode<ElemType> *root;
   public:
      BinaryTree():root(NULL){}
      BinaryTree(const ElemType &item){root = new BinaryTreeNode<ElemType>(item);}
      void makeBinaryTree( const ElemType &item, BinaryTree &left, BinaryTree &right);
      //返回二叉树结点的个数

      int BinaryTreeSize( BinaryTreeNode<ElemType> *T ) const;

      //判断二叉树是否为空

      bool BinaryTreeisEmpty() const{return root == NULL;}

      //获取根结点元素值

      ElemType GetRootData() const{ return root->data;}
      void SetRoot(BinaryTreeNode<ElemType> * p){ root = p;}
      BinaryTreeNode<ElemType> * GetRoot() const{ return root;}
      bool PreOrderTraverse( BinaryTreeNode<ElemType> *T );  //前序遍历(递归)//num的初始值为0,作用为控制输出格式(最后1个结点后不加“,”)
      bool InOrderTraverse( BinaryTreeNode<ElemType> *T );  //中序遍历(递归)
      bool PostOrderTraverse( BinaryTreeNode<ElemType> *T );  //后序遍历(递归)
      BinaryTreeNode<ElemType>* CreateBinaryTree(vector<ElemType> &x, ElemType &empty, int &n);
};

template<class ElemType>
BinaryTreeNode<ElemType>* BinaryTree<ElemType>::CreateBinaryTree(vector<ElemType> &x, ElemType &empty, int &n)
{
        ElemType ch = x[n];//string
        n++;
        if (ch == empty)
        {
            return NULL;
        }
        else
        {
            BinaryTreeNode<ElemType> *Node = new BinaryTreeNode<ElemType>;
            Node->data = ch;
            Node->LChild = CreateBinaryTree(x, empty, n);
            Node->RChild = CreateBinaryTree(x, empty, n);
            return Node;
        }
}
//辅助函数
bool isoperator( string op )
{
if( op == "+" || op == "-" || op == "*" || op == "/" || op == "(" || op == ")" )
   return true;
return false;
}
int getOperPri(string op)
{

        if(op=="(")
        return 1;
        else if(op=="+"||op=="-")
        return 2;
        else if(op=="*"||op=="/")
        return 3;
        else return 0;

}

//开始操作
template<class ElemType>
void BianryTree_Infix_Cursive(BinaryTreeNode<ElemType> *root, vector<ElemType> &inffix)
{
    if(root)
    {
        string t=" ",l=" ",r=" ";
        if(root->LChild&&root->RChild)
        {
            t=root->data;

            l=root->LChild->data;

            r=root->RChild->data;

        }
        if(isoperator(l)&&getOperPri(l)<getOperPri(t))
        {
            inffix.push_back("(");
            BianryTree_Infix_Cursive(root->LChild,inffix);
            inffix.push_back(")");
        }
        else
        {
            BianryTree_Infix_Cursive(root->LChild,inffix);
        }
        inffix.push_back(root->data);
        if(t=="+")
        {

            BianryTree_Infix_Cursive(root->RChild,inffix);

        }
        else if((t == "-" && isoperator(r)) &&(getOperPri(t) >= getOperPri(r)))
        {

            inffix.push_back("(");
            BianryTree_Infix_Cursive(root->RChild,inffix);
            inffix.push_back(")");
        }
        else if(t == "/" && isoperator(r))
        {
            inffix.push_back("(");
           BianryTree_Infix_Cursive(root->RChild,inffix);
            inffix.push_back(")");
        }
        else if((t=="*"&&isoperator(r))&&getOperPri(t)>getOperPri(r))
        {
            inffix.push_back("(");
           BianryTree_Infix_Cursive(root->RChild,inffix);
            inffix.push_back(")");
        }
        else
        {
            BianryTree_Infix_Cursive(root->RChild,inffix);
        }
    }

}
template<class ElemType>
void BianryTree_Infix(BinaryTree<ElemType> &T, vector<ElemType> &inffix)
{
    BianryTree_Infix_Cursive(T.GetRoot(),inffix);
}
template<class ElemType>
void CreateTree(BinaryTree<ElemType> &T, ElemType &str, ElemType &empty)
{
    ElemType tmp;
    vector<ElemType> t;
    stringstream input_T(str);
    while(input_T >> tmp)
    {
         t.push_back(tmp);
    }
    BinaryTreeNode<ElemType> *root;
    int num = 0;
    root = T.CreateBinaryTree(t, empty, num);
    T.SetRoot(root);
}
int main()
{
    BinaryTree<string> T;
    string str;
    string empty;
    getline(cin,empty);
    getline(cin,str);
    CreateTree(T,str,empty);
    vector<string> inffix;
    BianryTree_Infix(T,inffix);
    for(auto i : inffix)
    {
        if(i[0]=='-'&&i.size()>1)cout<<'('<<i<<')';
        else cout<<i;
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值