#include <iostream>
using namespace std;
void postOrder(string pre, string in) // 定义后序遍历函数,参数为前序遍历和中序遍历结果字符串
{
if (in.size())
{
char root = pre[0]; // 获取前序遍历结果的第一个字符作为根节点
int k = in.find(root); // 在中序遍历结果中找到根节点的位置
postOrder(pre.substr(1, k), in.substr(0, k)); // 递归处理左子树
postOrder(pre.substr(k + 1), in.substr(k + 1)); // 递归处理右子树
printf("%c", root); // 输出根节点
}
}
int main()
{
string preOrder, inOrder;
while (cin >> preOrder >> inOrder) // 循环读取输入的前序遍历和中序遍历结果
{
postOrder(preOrder, inOrder); // 调用后序遍历函数
cout << endl; // 输出换行符
}
return 0;
}
postOrder
函数接收两个参数:前序遍历结果字符串 pre
和中序遍历结果字符串 in
。
在 postOrder
函数中,首先判断中序遍历结果字符串 in
是否为空,如果不为空,则说明当前节点有子节点需要处理。接着,获取前序遍历结果的第一个字符作为根节点,并在中序遍历结果中找到该根节点的位置 k
。
然后,递归调用 postOrder
函数处理左子树和右子树。具体来说,对于左子树,传入的前序遍历结果字符串为 pre.substr(1, k)
,中序遍历结果字符串为 in.substr(0, k)
;对于右子树,传入的前序遍历结果字符串为 pre.substr(k + 1)
,中序遍历结果字符串为 in.substr(k + 1)
。
最后,输出根节点的值。这样,通过递归调用 postOrder
函数,就可以按照后序遍历的顺序输出整个二叉树的节点值。
pre.substr(1, k)
和 in.substr(0, k)
用于获取左子树的前序遍历和中序遍历结果,而 pre.substr(k + 1)
和 in.substr(k + 1)
用于获取右子树的前序遍历和中序遍历结果。这些参数的取值是基于二叉树的前序遍历和中序遍历的特性。
前序遍历和中序遍历的特性:
- 前序遍历:根节点 -> 左子树 -> 右子树
- 中序遍历:左子树 -> 根节点 -> 右子树
参数解释:
-
pre.substr(1, k)
:从前序遍历字符串中提取左子树的前序遍历结果。由于前序遍历是先访问根节点,然后是左子树,最后是右子树,因此左子树的前序遍历结果从第二个字符开始(索引为1),长度为k
(因为根节点已经在pre[0]
中处理过了)。 -
in.substr(0, k)
:从中序遍历字符串中提取左子树的中序遍历结果。由于中序遍历是先访问左子树,然后是根节点,最后是右子树,因此左子树的中序遍历结果从第一个字符开始(索引为0),长度为k
(因为根节点已经在中序遍历的k
位置找到了)。 -
pre.substr(k + 1)
和in.substr(k + 1)
:这些用于提取右子树的前序遍历和中序遍历结果。由于左子树的最后一个节点在中序遍历中的索引是k
,因此右子树的部分从k + 1
开始。
总结:
这些参数的取值是为了确保正确地从原始的前序遍历和中序遍历字符串中提取出左子树和右子树对应的部分。这样,递归调用 postOrder
函数时,可以正确地处理每个子树。