跳转至

一本通-1366:二叉树输出(btout)

【题目描述】 树的凹入表示法主要用于树的屏幕或打印输出,其表示的基本思想是兄弟间等长,一个结点的长度要不小于其子结点的长度。二叉树也可以这样表示,假设叶结点的长度为1,一个非叶结点的长度等于它的左右子树的长度之和。

一棵二叉树的一个结点用一个字母表示(无重复),输出时从根结点开始:

每行输出若干个结点字符(相同字符的个数等于该结点长度),如果该结点有左子树就递归输出左子树;如果该结点有右子树就递归输出右子树。

假定一棵二叉树一个结点用一个字符描述,现在给出先序和中序遍历的字符串,用树的凹入表示法输出该二叉树。

【输入】 两行,每行是由字母组成的字符串(一行的每个字符都是唯一的),分别表示二叉树的先序遍历和中序遍历的序列。

【输出】 行数等于该树的结点数,每行的字母相同。

【输入样例】 ABCDEFG CBDAFEG

【输出样例】 AAAA BB C D EE F G


题目的意思是要根据每个节点的长度然后前序遍历输出,关键点在于如何确定节点长度。在二叉树的每个节点额外保存一个频率信息freq,首先是根据前序和中序遍历结果建树,然后递归的去计算节点的频率信息,最后递归实现前序遍历即可。

#include <bits/stdc++.h>

using namespace std;

string preorder, inorder;

struct TreeNode
{
    char ch;
    int freq;
    TreeNode *left, *right;
    TreeNode(char x): ch(x), freq(0), left(NULL), right(NULL) {}
};


TreeNode *build(int pre_start, int pre_end, int in_start, int in_end)
{
    if (pre_start == pre_end || in_start == in_end) return NULL;

    TreeNode *root = new TreeNode(preorder[pre_start]);
    int pos = inorder.find(preorder[pre_start]);
    int leftSize = pos - in_start;

    root -> left = build(pre_start + 1, pre_start + 1 + leftSize, in_start, pos);
    root -> right = build(pre_start + 1 + leftSize, pre_end, pos + 1, in_end);

    return root;
}


void makeEmpty(TreeNode *&root)
{
    if (root) {
        makeEmpty(root -> left);
        makeEmpty(root -> right);
        delete root;
        root = NULL;
    }
}

void calculateFreq(TreeNode *root)
{
    if (!root) return;
    if (!root -> left && !root -> right) {
        root -> freq = 1;
        return;
    }

    calculateFreq(root -> left); 
    calculateFreq(root -> right);
    root -> freq = (root -> left ? root -> left -> freq : 0) 
        + (root -> right ? root -> right -> freq : 0);
}

void preorderTraversal(TreeNode *root)
{
    if (!root) return;

    for (int i = 0; i < root -> freq; ++i) {
        cout << root -> ch;
    }
    cout << endl;
    preorderTraversal(root -> left);
    preorderTraversal(root -> right);
}

int main()
{
    std::ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    cin >> preorder >> inorder;

    TreeNode *root = build(0, preorder.size(), 0, inorder.size());
    calculateFreq(root);

    preorderTraversal(root);

    makeEmpty(root);

    return 0;
}