问题:已知一个二叉树前序遍历为:ABDEGCFH,中序遍历为:DBGEACHF,则该二叉树的后序遍历为?python
思路是这样的:1:根据前序遍从来肯定每次根节点的位置,由于前序遍历先访问的是根节点,因此前序遍历第一个位置就是根节点。 2:根据根节点和中序遍历将树划分为左右两棵树。3:根据第一步和第二步递归的处理左右两棵树。post
第一步:根据前序遍历 A B D E G C F H 肯定头结点是A,根据中序遍历 D B G E A C H F 将树划分为左子树 D B G E 和右子树 C H F。
第二步:划分为左右两棵子树:对于左子树,前序遍历是 B D E G,后续遍历是 D B G E。对于右子树,前序遍历是 C F H,后续遍历是 C H F。
第三步:对左子树和右子树分别运用第一步和第二步进行分析。
递归结束的条件:当中序遍历的节点只剩下一个节点的时候,那么这个节点就是叶子节点。ui
总体的操做流程以下:
code
Python代码以下:blog
class TreeNode: """树节点""" def __init__(self, x): self.val = x self.left = None self.right = None class Solution: def reConstructBinaryTree(self, pre, tin): """根据前序遍历和中序遍从来重建一颗二叉树,要求前序遍历和中序遍历当中字符不重复 Args: pre: 前序遍历 list类型或者者str类型 tin: 中序遍历 Returns: head: 一个TreeNode类型的根节点 """ return self.rebuild_tree(pre, 0, len(pre)-1, tin, 0, len(tin)-1) def rebuild_tree(self, pre, pre_start, pre_end, tin, tin_start, tin_end): """递归的进行树的重建""" if pre_start > pre_end or tin_start > tin_end: return None head = TreeNode(pre[pre_start]) tin_mid = tin.index(pre[pre_start]) left_length = tin_mid - tin_start head.left = self.rebuild_tree(pre, pre_start+1, pre_start+left_length, tin, tin_start, tin_mid-1) head.right = self.rebuild_tree(pre,pre_start+left_length+1, pre_end, tin, tin_mid+1, tin_end) return head def post_order_print(head): """之后序遍历的方式打印一颗二叉树""" if head is None: return post_order_print(head.left) post_order_print(head.right) print(head.val,end='') if __name__ == '__main__': pre = 'ABDEGCFH' tin = 'DBGEACHF' s = Solution() head = s.reConstructBinaryTree(pre, tin) post_order_print(head) # result: DGEBHFCA
道理是同样的,根据后序遍从来肯定根节点的位置,因为后序遍历最后访问根节点, 因此此时最后一个节点就是根节点。根据中序遍从来划分左右子树,而后迭代求解。递归
前序和后序在本质上都是将父节点与子结点进行分离,但并无指明左子树和右子树的能力,所以获得这两个序列只能明确父子关系,而不能肯定一个二叉树。
好比前序遍历为ABC,后续遍历为CBA,能够构造出下面两棵树,能够发现这并不惟一:
it