由先序和中序求后序
二叉树是数据结构中常用的一种结构,它包含节点和指向左右子树的指针。常见的树的遍历方式包括先序遍历、中序遍历和后序遍历。其中,先序遍历是指以根节点为起点,先访问根节点,然后访问左子树,最后访问右子树;中序遍历是指以根节点为起点,先访问左子树,然后访问根节点,最后访问右子树;后序遍历是指以根节点为起点,先访问左子树,然后访问右子树,最后访问根节点。
当我们知道一棵二叉树的先序遍历和中序遍历时,我们可以通过推导来求出二叉树的后序遍历。
首先,我们需要明确一点,先序遍历的第一个值一定是整棵树的根节点。因此,我们可以根据先序遍历的第一个值找到中序遍历中对应的位置,从而确定根节点的位置。比如下面这棵二叉树:
```
1
/ \
2 3
/ \ / \
4 5 6 7
```
它的先序遍历为:1,2,4,5,3,6,7
它的中序遍历为:4,2,5,1,6,3,7
我们可以根据先序遍历的第一个值1,确定根节点在中序遍历中的位置为第4个位置。因此,根据中序遍历的性质,我们可以确定子树的规模。即根节点前面的是左子树,后面的是右子树。即4,2,5是左子树,6,3,7是右子树。
接着,我们可以通过递归来求出左子树和右子树的后序遍历。递归的思想是将问题切分为若干个小问题,然后通过逐步推导来解决问题。对于左子树和右子树来说,也可以采用同样的递归方式推导后序遍历。
我们可以得到如下算法:
1. 传入先序序列,中序序列,以及树的规模。对于整棵树来说,规模为序列长度。 对于子树来说,规模为左子树或右子树的长度。
2. 根据先序序列找到根节点,然后找到根节点在中序序列中的位置
3. 根据根节点在中序序列中的位置,确定左子树和右子树,并分别计算左子树和右子树的规模
4. 递归求出左子树和右子树的后序遍历
5. 将根节点加入到后序序列中。
6. 返回后序序列。
具体实现方法可以参考下面的代码:
```python
def get_post_order(preorder, inorder, size):
if size <= 0:
return []
root = preorder[0]
root_pos = inorder.index(root)
left_size = root_pos
right_size = size - left_size - 1
left = get_post_order(preorder[1:left_size + 1], inorder[:root_pos], left_size)
right = get_post_order(preorder[left_size + 1:], inorder[root_pos + 1:], right_size)
return left + right + [root]
```
需要注意的是,这里的代码基于下标操作。在实际应用中,可能需要用到哈希表来加速查找。
另外,有些题目可能还会要求我们输出后序遍历的字符串表示,而不仅仅是后序遍历的序列。这时我们可以修改算法,将后序遍历直接输出。即,在递归过程中,递归求解左子树和右子树的后序遍历,然后将根节点加入到后序遍历中。
综上,我们可以通过给定先序遍历和中序遍历的方式来求出二叉树的后序遍历。这是一种基于递归的思想,通过不断缩小问题规模,来逐步推导出最终答案的方法。在实际应用中,我们可能还需要加入一些优化,比如哈希表等技巧来提高效率。但总的来说,这种方法比较通用,也相对容易理解,非常实用。