根据中序遍历结果和前序(后序)遍历结果重构二叉树
2016-06-21 13:30
411 查看
问题描述:输入某二叉树的中序和前序(后序)遍历结果,请重构出该二叉树。
首先,我们需要回顾二叉树的三种遍历方式:
前序遍历:根+左子树+右子树
中序遍历:左子树+根+右子树
后序遍历:左子树+右子树+根
假设,当前二叉树的前序遍历结果为{1,2,4,5,3,6},中序遍历结果为{4,2,5,1,3,6}
我们首先尝试分步构造:
1.前序遍历的第一个元素,必然是树根,此处为1。
那么我们可以构造出如下图所示的二叉树:
2.根据“1”在中序出现的位置,将中序遍历的结果分成左右两棵子树,它们的中序遍历分别是:
{4,2,5} 和{3,6};这两棵子树的前序结果:{2,4,5}和{3,6}。
3.现在我们重复步骤1、2,构造左子树,如下图所示:
4.现在我们重复步骤1、2,构造右子树,如下图所示:
5.合并树节点得到最终结果:
结合以上步骤,我们可以总结出如下规律:
1.根据前序(后序也适用)遍历结果,找到树根,设为ROOT,并生成一个以ROOT为根节点,左右子树
都为NULL的树
2.根据ROOT在中序遍历中的索引,将中序遍历结果分为:左子树,右子树;同时我们也要明确左右子树
对应的前序(后序)遍历结果
3.递归的执行步骤1和2即可构造出唯一的二叉树。
关于二叉树的定义,这里就不给出了,下面提供了根据中序和前序遍历结果重构二叉树的关键代码(Java实现):
扩展思考:
根据前序与后序结果,可以重构出唯一的二叉树吗?
答案是不一定。
证明如下:
情况一:假设前序结果是{3,1,2},后序结果是{2,1,3}
那么二叉树的结构可能如下:
3
/
1
/
2
3
\
1
\
2
这种情况下,二叉树并不唯一;
情况二:假设前序结果是{3,1,2},后序结果是{1,2,3}
那么二叉树的结构如下:
3
/ \
1 2
首先,我们需要回顾二叉树的三种遍历方式:
前序遍历:根+左子树+右子树
中序遍历:左子树+根+右子树
后序遍历:左子树+右子树+根
假设,当前二叉树的前序遍历结果为{1,2,4,5,3,6},中序遍历结果为{4,2,5,1,3,6}
我们首先尝试分步构造:
1.前序遍历的第一个元素,必然是树根,此处为1。
那么我们可以构造出如下图所示的二叉树:
2.根据“1”在中序出现的位置,将中序遍历的结果分成左右两棵子树,它们的中序遍历分别是:
{4,2,5} 和{3,6};这两棵子树的前序结果:{2,4,5}和{3,6}。
3.现在我们重复步骤1、2,构造左子树,如下图所示:
4.现在我们重复步骤1、2,构造右子树,如下图所示:
5.合并树节点得到最终结果:
结合以上步骤,我们可以总结出如下规律:
1.根据前序(后序也适用)遍历结果,找到树根,设为ROOT,并生成一个以ROOT为根节点,左右子树
都为NULL的树
2.根据ROOT在中序遍历中的索引,将中序遍历结果分为:左子树,右子树;同时我们也要明确左右子树
对应的前序(后序)遍历结果
3.递归的执行步骤1和2即可构造出唯一的二叉树。
关于二叉树的定义,这里就不给出了,下面提供了根据中序和前序遍历结果重构二叉树的关键代码(Java实现):
/** * 根据前序和中序遍历数组重构二叉树 * @param preOrder:前序遍历数组 * @param inOrder:中序遍历数组 * @return root:二叉树 */ static BinaryTree reBuildBinaryTree(Object[] preOrder,Object[] inOrder){ //递归退出条件 if (preOrder == null || inOrder == null || preOrder.length == 0 || inOrder.length == 0) { return null; } // 前序遍历的结果的第一个元素即为二叉树的根节点 BinaryTree root=new BinaryTree(preOrder[0]); //根节点在中序遍历中的索引 int i=0; // 获取根节点在中序遍历中的索引 for (;i < inOrder.length;i++) { if (inOrder[i] == preOrder[0]) { break; } } //构造左子树的前序和中序数组 Object[] leftPre = Arrays.copyOfRange(preOrder, 1, i + 1); Object[] leftIn = Arrays.copyOfRange(inOrder, 0, i); //构造右子树的前序和中序数组 Object[] rightPre = Arrays.copyOfRange(preOrder, i + 1, preOrder.length); Object[] rightIn = Arrays.copyOfRange(inOrder, i + 1, inOrder.length); //递归构建当前根节点的左子树 root.left = reBuildBinaryTree(leftPre, leftIn); //递归构建当前根节点的右子树 root.right = reBuildBinaryTree(rightPre, rightIn); //递归构建二叉树完成, 返回根节点 return root; }
扩展思考:
根据前序与后序结果,可以重构出唯一的二叉树吗?
答案是不一定。
证明如下:
情况一:假设前序结果是{3,1,2},后序结果是{2,1,3}
那么二叉树的结构可能如下:
3
/
1
/
2
3
\
1
\
2
这种情况下,二叉树并不唯一;
情况二:假设前序结果是{3,1,2},后序结果是{1,2,3}
那么二叉树的结构如下:
3
/ \
1 2
相关文章推荐
- AVL树-自平衡二叉查找树(Java实现)
- 文件遍历排序函数
- Lua 学习笔记之C API 遍历 Table实现代码
- C#遍历文件夹后上传文件夹中所有文件错误案例分析
- C#中遍历Hashtable的4种方法
- Erlang中遍历取出某个位置的最大值代码
- C++实现图的邻接矩阵存储和广度、深度优先遍历实例分析
- C++实现图的邻接表存储和广度优先遍历实例分析
- C语言二叉树的非递归遍历实例分析
- 使用C语言构建基本的二叉树数据结构
- 一波二叉树遍历问题的C++解答实例分享
- 举例讲解C语言程序中对二叉树数据结构的各种遍历方式
- C++非递归队列实现二叉树的广度优先遍历
- php遍历目录方法小结
- 一个目录遍历函数
- php遍历删除整个目录及文件的方法
- PHP遍历文件夹与文件类及处理类用法实例
- PHP遍历XML文档所有节点的方法
- 如何用微服务重构应用程序
- 平衡二叉树