day51 计算机考研408真题2017年41题(C++)

211 阅读2分钟

题目来源: 计算机考研408真题2017年41题

题目描述:

  • 描述: 41.(15分)请设计一个算法,将给定的表达式树(二叉树)转换为等价的中级表达式(通过括 号反映操作符的计算次序)并输出,例如,当下列两棵表达式树作为算法的输入时,输出的等价中级表达式分别为(a+b)(c(d))(ab)+((cd))(a+b)*(c*(-d))和(a*b)+(-(c-d))image.png 二叉树结点定义如下:
typedef struct node{
    char data[10];   //存储操作数或操作符
    struct node * left,*right;
}BTree;

要求:
1)给出算法的基本设计思想。
2)根据设计思想,采用C、C++或Java语言描述算法,关键之处给出注释.
3)说明你所设计算法的时间复杂度和空间复杂度。

  • 示例:
输入:*+a##b##*c##-#d##
输出:((a+b)*(c*(-d)))
说明:上图中左图的数据,其中#代指叶子结点的左右孩子

输入:+*a##b##-#-c##d##
输出:((a*b)+(-(c-d)))
说明:上图中右图的数据

思路:基于二叉树的中序遍历

  • 表达式树的中序序列加上必要的括号即为等价的中缀表达式。可以基于二叉树的中序遍历得到所需的表达式。
  • 在生成遍历序列的同时,在适当位置增加必要的括号,才能得到正确的中缀表达式。
    • 表达式的最外层(对应根结点)及操作数(对应叶结点)不需要添加括号。
  • 注意: 方法传入参数时,注意参数应该是指针还是引用,会影响到结果

具体实现:

#include <iostream>

using namespace std;

typedef struct Node {
    char data;  //数据域
    struct Node *left, *right;  //指针域 

    Node(char val) {   //结构体初始化
        /*
         * 构造函数初始化常见于 C++ 代码中,
         * 因为 C++ 中的 struct 可以看作 class,
         * 结构体也可以拥有构造函数,
         * 所以我们可以通过结构体的构造函数来初始化结构体对象
         */
        this->data = val;
        this->left = NULL;
        this->right = NULL;
    }
} Node, *Btree;

void buildTree_PreOrder(Btree& T) {  //这里的参数一定要用引用
    char data;
    cin >> data;
    if (data == '#') T = NULL;  //这是自己指定的判断叶子结点的左右孩子的依据)
    else
    {   //按照先序遍历进行创建二叉树:根 左 右
        T = new Node(data);
        buildTree_PreOrder(T->left);
        buildTree_PreOrder(T->right);
    }
}

void BtreeToE(Btree &T) {
    if (T == NULL) return;    //如果是空节点,则返回
    else if (T->left == NULL && T->right == NULL)  //如果是叶子结点
        cout << T->data;      //输出操作数,不加括号
    else{
        cout<<"(";
        BtreeToE(T->left);
        cout<<T->data;
        BtreeToE(T->right);
        cout<<")";
    }

}

int main() {   //测试
    Btree T;
    buildTree_PreOrder(T);
    BtreeToE(T);
}

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 25 天,点击查看活动详情