9 二叉树的重建

问题描述 :

目的:现有两个结点序列,分别是对同一个二叉树进行前序遍历和中序遍历(或中序和后序)的结果。要求设计一个算法,重构该二叉树,并输出该二叉树按照后序(前序)遍历时的结点序列。假定二叉树所有的结点的数据域的值都不相同。二叉树的存储结构的建立参见二叉树应用1。

一、已知前序和中序的结果,进行二叉树的重构:

提示:preOrder按照先根再左再右的顺序递归遍历,inOrder按照先左再根再右的顺序递归遍历。

举例说明:preOrder的输入pre={A,B,D,G,H,C,E,I,F},inOrder的输入in={G,D,H,B,A,E,I,C,F}。首先按preOrder遍历的顺序依次访问各结点。访问过程中,通过in得知各子树内inOrder遍历的顺序,从而重建以当前访问结点c为根的左子树与右子树。即:设preOrder遍历的当前结点为c,c在in中的位置为m,m左侧就是c的左子树,右侧就是c的右子树。同理递归。

(2)

参考函数原型:

(1)//重建二叉树的存储结构 (外壳)
template<class ElemType>
BinaryTreeNode<ElemType> *ReBuildTree_Pre_In(vector[ElemType] &pre, vector[ElemType] &in);

(2)//重建二叉树的存储结构 (递归)
template<class ElemType>
BinaryTreeNode<ElemType> *reConstructCore_Pre_In(vector[ElemType] &pre, vector[ElemType] &in, int preStart, int preEnd, int inStart, int inEnd );

二、已知中序和后序的结果,进行二叉树的重构:

可参考一的思路。

参考函数原型:

(1)//重建二叉树的存储结构 (外壳)
template<class ElemType>
BinaryTreeNode<ElemType> *ReBuildTree_In_Post(vector[ElemType] &in, vector[ElemType] &post);

(2)//重建二叉树的存储结构 (递归)
template<class ElemType>
BinaryTreeNode<ElemType> *reConstructCore_In_Post(vector[ElemType] &in, vector[ElemType] &post, int inStart, int inEnd, int postStart, int postEnd );

输入说明 :

第一行:重构选择(0:前序中序重构  1:中序后序重构)  

0:

第二行:按前序遍历的结点序列,相邻结点用空格隔开

第三行:按中序遍历的结点序列,相邻结点用空格隔开

1:

第二行:按中序遍历的结点序列,相邻结点用空格隔开

第三行:按后序遍历的结点序列,相邻结点用空格隔开

输出说明 :

0:

第一行:按后序遍历的结点序列,相邻结点用","隔开

1:

第一行:按前序遍历的结点序列,相邻结点用","隔开

/*
*
string build(int iStart, int iEnd, int pStart, int pEnd) {
    string root = Post[pEnd];
    int k = Pos[root];
    if (iStart < k)lChild[root] = build(iStart, k - 1, pStart, pStart + k - 1 - iStart);
    if (iEnd > k)rChild[root] = build(k + 1, iEnd, pStart + k - iStart, pEnd - 1);
    ///列两个方程
    /*
    *            左子树    根  右子树
      Inorder:|___________ - ___________|
              iSt      k-1 k k+1       iEnd

                  左子树      右子树      根
    Postorder:|____________|____________|
              pSt         X|X+1        pEnd

              得到如下方程
              X - pSt = k - 1 - iSt;
              pEnd - Y = iEND - ( K + 1 );
              return root;
 }
}
*/
template<class T>
struct TreeNode {
    T val;
    int id = 0;
    int flag = 1;
    TreeNode* left;
    TreeNode* right;
    TreeNode() : left(nullptr), right(nullptr) {}
    TreeNode(T x) : val(x), left(nullptr), right(nullptr) {}
    TreeNode(T x, TreeNode* left, TreeNode* right) : val(x), left(left), right(right) {}
};
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
template<class T>
TreeNode<T>* build(T empty) {
    T val;
    cin >> val;
    if (val != empty) {
        TreeNode<T>* node = new TreeNode<T>(val);
        node->left = build<T>(empty);
        node->right = build<T>(empty);
        return node;
    }
    else {
        return NULL;
    }
}
#include <queue>
template<class T>
TreeNode<T>* buildlayer(T empty) {
    string str;
    getline(cin, str);
    stringstream ss(str);
    TreeNode<T>* head = new TreeNode<T>("");
    queue< TreeNode<T>*>q;
    q.push(head);
    while (ss >> str) {
        TreeNode<T>* obj = q.front();
        q.pop();
        if (str != empty) {
            obj->val = str;
            obj->flag = 1;
            obj->left = new TreeNode<T>("");
            obj->left->flag = 0;
            obj->right = new TreeNode<T>("");
            obj->right->flag = 0;
            q.push(obj->left);
            q.push(obj->right);
        }
    }
    while (q.size()) {
        q.front()->flag = 0;
        q.pop();
    }
    return head;
}
template<class T>
void preorder(TreeNode<T>* tree, vector<T>& list) {
    if (tree) {
        if (tree->flag)list.push_back(tree->val);
        preorder(tree->left, list);
        preorder(tree->right, list);
    }
}
template<class T>
void inorder(TreeNode<T>* tree, vector<T>& list) {
    if (tree) {

        inorder(tree->left, list);
        if (tree->flag)list.push_back(tree->val);
        inorder(tree->right, list);
    }
}
template<class T>
TreeNode<T>* seek(TreeNode<T>* t, T target) {
    if (!t)return NULL;
    if (t->val == target)return t;
    auto l = seek(t->left, target), r = seek(t->right, target);
    if (l)return l;
    else return r;
}
template<class T>
TreeNode<T>* seekparent(TreeNode<T>* t, T target) {
    if (!t)return NULL;
    if (t->val == target)return NULL;
    if (t->left && t->left->val == target || t->right && t->right->val == target)
        return t;
    else {
        auto l = seekparent(t->left, target), r = seekparent(t->right, target);
        if (l)return l;
        else return r;
    }
}
template<class T>
void postorder(TreeNode<T>* tree, vector<T>& list) {
    if (tree) {
        postorder(tree->left, list);
        postorder(tree->right, list);
        if (tree->flag)list.push_back(tree->val);
    }
}
template<class T>
void out(TreeNode<T>* head,int flag) {
    vector<T>pr, po;
    preorder(head, pr);
    //inorder(head, in);
    postorder(head, po);
    if (!flag) {
        for (int i = 0; i < po.size(); ++i)
            cout << po[i] << ",\n"[i == po.size() - 1];

    }
    else {
        for (int i = 0; i < pr.size(); ++i)
            cout << pr[i] << ",\n"[i == pr.size() - 1];
    }

    //for (int i = 0; i < in.size(); ++i)
    //    cout << in[i] << ",\n"[i == in.size() - 1];


}
#include <unordered_map>
unordered_map<string, int>inPos;
vector<string>pre, in, post;
TreeNode<string>* buildpost(int il,int ir,int pl,int pr) {
    TreeNode<string>* root = new TreeNode<string>(post[pr]);
    int k = inPos[root->val];
    if (il < k)
        root->left = buildpost(il, k - 1, pl, pl + k - 1 - il);
    if (ir > k)
        root->right = buildpost(k + 1, ir, pl + k - il, pr - 1);
    return root;
}
TreeNode<string>* buildpre(int il, int ir, int pl, int pr) {
    TreeNode<string>* root=new TreeNode<string>(pre[pl]);
    int k = inPos[root->val];
    if (il < k)root->left = buildpre(il, k - 1, pl + 1, pl + k - il);
    if (ir > k)root->right = buildpre(k + 1, ir, pl + k - il + 1, pr);
    return root;
    //              左子树         根           右子树
    //    Inorder : | ___________ - ___________ |
    //              iSt     k - 1 k k + 1       iEnd

    //               根             左子树         右子树
    //    Preorder : | ____________ | ____________ |
    //              pSt           X | X + 1        pEnd

    //    得到如下方程
    //    X - pSt = k - 1 - iSt;
    //pEnd - Y = iEND - (K + 1);
}


int n;
int main() {
    int flag;
    cin >> flag;
    getchar();
    if (!flag) {
        string src;
        getline(cin, src);
        stringstream ss(src);
        while (ss >> src)pre.push_back(src);
        getline(cin, src);
        stringstream ss2(src);
        int i = 0;
        while (ss2 >> src) {
            in.push_back(src);
            inPos[src] = i++;
        }
        n = in.size();
        out(buildpre(0, n - 1, 0, n - 1),flag);
    }
    else {
        string src;
        getline(cin, src);
        stringstream ss(src);
        int i = 0;
        while (ss >> src) {
            in.push_back(src);
            inPos[src] = i++;
        }
        getline(cin, src);
        stringstream ss2(src);
        while (ss2 >> src)post.push_back(src);
        n = in.size();
        out(buildpost(0, n - 1, 0, n - 1), flag);
    }

    return 0;
}

程序设计基础OJ原题,带注释版本.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值