问题描述 :
目的:现有两个结点序列,分别是对同一个二叉树进行前序遍历和中序遍历(或中序和后序)的结果。要求设计一个算法,重构该二叉树,并输出该二叉树按照后序(前序)遍历时的结点序列。假定二叉树所有的结点的数据域的值都不相同。二叉树的存储结构的建立参见二叉树应用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原题,带注释版本.