先来看看最简单的三个元素的情况:
中序遍历inorder的序列为:B A C
后序遍历postorde的序列为: B C A
为了构造这颗二叉树,我们分三步走:
(1)找root结点。
利用后序遍历序列。由后续序列我们很容易得到这颗二叉树的root为A。
(2)找root的左子树。
利用中序遍历序列。在中序序列中找到root结点A,A的左边的序列B就是root的左子树。
(3)找root的右子树。
同样利用中序遍历序列。在中序序列中找到root结点A,A的右边的序列C就是root的右子树。
这是简单的三个元素的情况,当情况复杂时候,我们可以用上面的三条规则递归构造就可以了。
下面的测试代码,可供参考
#include <vector> #include <algorithm> #include <iostream> using namespace std; /** * definite a binarytree * * */ struct TreeNode { int val; TreeNode *left, *right; TreeNode(int x) :val(x), left(NULL), right(NULL){} }; class Solution { public: Solution(); ~Solution(); TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder); private: }; Solution::Solution() { } Solution::~Solution() { } TreeNode *Solution::buildTree(vector<int> &inorder, vector<int> &postorder) { TreeNode *root = new TreeNode(postorder.back()); if (inorder.size() == 0 || postorder.size() == 0) { return NULL; } if (inorder.size() == 1) { return root; } vector<int>::iterator a = find(begin(inorder), end(inorder), postorder.back());// find() return an iterator vector<int> left(inorder.begin(), a);//中序序列的左边部分 vector<int> right(a + 1, inorder.end());//中序序列的右边部分 vector<int>::iterator b = find(postorder.begin(), postorder.end(), right.front()); vector<int> left_p(postorder.begin(), b);左边部分对应的后序序列 vector<int> right_p(b, postorder.end()-1);右边部分对应的后序序列 root->left = buildTree(left,left_p);//递归左子树 root->right = buildTree(right,right_p);//递归右子树 return root; } template<typename T> std::ostream &operator<<(std::ostream &s, const std::vector<T> &v) { for (const auto e : v) { s << e << " "; } return s; } void printTreeBypreorder(const TreeNode *root) { if (root) { cout << root->val << " "; printTreeBypreorder(root->left); printTreeBypreorder(root->right); } else { return; } } int main() { vector<int> inorder{ 4, 2, 5, 1, 6, 3, 7 }; vector<int> postorder{ 4, 5, 2, 6, 7, 3, 1 }; Solution solu; TreeNode *result = solu.buildTree(inorder, postorder); printTreeBypreorder(result); return 0; }