比如对于前序:1,2,4,8,9,5,10,11,3,6,12,13,7
后序:8,4,9,2,10,5,11,1,12,6,13,3,7
建成的树应该是1-13的满二叉,后序遍历为:8,9,4,10,,11,5,2,12,13,6,7,3,1
主要思想就是把前序放在上面,后序放在下面,依次从后序找到这个前序的位置,建立左右子树。具体思想还得画图,我就不说啦,还是贴代码吧:
#ifndef _BINARY_TREE_H_
#define _BINARY_TREE_H_
#include <cassert>
#include <vector>
#include <stack>
using namespace std;
template<typename T>
struct tree_node
{
T val;
tree_node* left;
tree_node* right;
explicit tree_node(const T val_)
: val(val_), left(NULL), right(NULL){}
};
template<typename T>
struct binary_tree_default_traverser
{
void operator()(const tree_node<T>* node) const
{
cout << node->val << ", ";
}
};
template<typename T, typename Pred>
void post_traverse(const tree_node<T>* root, const Pred& pred)
{
if (root == NULL)
{//
return;
}
post_traverse(root->left);
post_traverse(root->right);
pred(root);
}
template<typename T>
void post_traverse(const tree_node<T>* root)
{
binary_tree_default_traverser<T> t;
post_traverse(root, t);
}
template<typename T>
tree_node<T>* build_tree(const vector<T>& pre_order, const vector<T>& in_order)
{
tree_node<T>* root1 = build_tree_iteratorly(pre_order, in_order);
size_t ptr = 0;
tree_node<T>* root2 = build_tree_recursively(pre_order, ptr,
in_order, 0, in_order.size());
post_traverse(root2);
return NULL;
}
template<typename T>
static size_t find_in_in(const vector<T>& in_order, const T& target, size_t left, size_t right)
{
size_t ret(left);
for (; ret < right; ret++)
{//
if (in_order[ret] == target)
{//
return ret;
}
}
return ret;
}
template<typename T>
tree_node<T>* build_tree_iteratorly(const vector<T>& pre_order,const vector<T>& in_order)
{
//定义在函数内部,不能调试了。。。
typedef struct container
{
size_t left;
size_t right;
tree_node<T>** self;
container(size_t left_, size_t right_, tree_node<T>** self_)
: left(left_), right(right_), self(self_){}
}container_t;
//初始化栈
stack<container_t> s;
size_t ptr = 0;
tree_node<T>* root = new tree_node<T>(pre_order[ptr]);
size_t pos = find_in_in(in_order, pre_order[ptr], 0, pre_order.size());
container_t left(0, pos, &root->left);
container_t right(pos+1, pre_order.size(), &root->right);
s.push(right);
s.push(left);
ptr++;
//处理
while (!s.empty())
{//
container_t c = s.top();
s.pop();
if (c.right == c.left)
{//
*c.self = NULL;
}
else
{
tree_node<T>* root = new tree_node<T>(pre_order[ptr]);
size_t pos = find_in_in(in_order, pre_order[ptr], c.left, c.right);
*(c.self) = root;
container_t left(c.left, pos, &root->left);
container_t right(pos+1, c.right, &root->right);
//先放右子树,再放左子树
s.push(right);
s.push(left);
ptr++;
}
}
assert(ptr == pre_order.size());
return NULL;
}
template<typename T>
tree_node<T>* build_tree_recursively(const vector<T>& pre_order,size_t& ptr,const vector<T>& in_order,size_t left, size_t right)
{
//跟iteratorly不同,不让它出现left==right的情况,
//如果出现的话,ptr的处理会比较复杂
if (right - left == 1)
{//
tree_node<T>* node = new tree_node<T>(pre_order[ptr]);
node->left = node->right = NULL;
return node;
}
tree_node<T>* node = new tree_node<T>(pre_order[ptr]);
size_t pos = find_in_in(in_order, pre_order[ptr], left, right);
++ptr;
node->left = build_tree_recursively(pre_order, ptr, in_order, left, pos);
++ptr;
node->right = build_tree_recursively(pre_order, ptr, in_order, pos+1, right);
return node;
}
void build_tree_test()
{
int pre[] = {1,2,4,8,9,5,10,11,3,6,12,13,7};
int in[] = {8,4,9,2,10,5,11,1,12,6,13,3,7};
vector<int> pre_order(pre, pre+13);
vector<int> in_order(in, in+13);
build_tree(pre_order, in_order);
}
#endif