Here is the code for the answer explained above (the use of std::vector is inefficient):
std::vector postorder(std::vector& preorder,
std::vector& inorder,
int min_pos, /* Position of min value of subtree in inorder representation */
int max_pos, /* Position of max value of subtree in inorder representation */
int& next_root_pos /* Index in preorder representation for finding next root node */
)
{
std::vector res;
// Value of the root for the current tree
int root = preorder[next_root_pos];
// Find the position of this value in the preorder traversal
int root_in_inorder_index = 0;
while (inorder[root_in_inorder_index] != root)
root_in_inorder_index++;
// Left subtree
if (min_pos != root_in_inorder_index)
{
next_root_pos++;
std::vector left = postorder(preorder,
inorder,
min_pos,
root_in_inorder_index - 1,
next_root_pos);
res.insert(res.end(), left.begin(), left.end());
}
if (max_pos != root_in_inorder_index)
{
// Right subtree
next_root_pos++;
std::vector right = postorder(preorder,
inorder,
root_in_inorder_index + 1,
max_pos,
next_root_pos);
res.insert(res.end(), right.begin(), right.end());
}
// Current element
res.push_back(root);
return res;
}