二叉树前序后序中序互推总结
来源:互联网 发布:淘宝 全球购 费用 编辑:程序博客网 时间:2024/06/11 10:32
最近笔试题一直遇到这个题,今天就总结一下。本文主要回答以下几个问题(Java实现):
- 前序 + 中序 => 后序 + 层序
- 后序 + 中序 => 前序 + 层序
- 以上2个问题的2种解决办法(a. 手写出二叉树 b. 编程实现)
先看以下3种遍历的特点:
特点:
- 前序的第一个是root,后序的最后一个是root。
- 每种排序左子树右子树分布都是有规律的,见上图。
- 对于每一个子树(左/右)可以看成一个全新的树,仍然遵循上面的规律。
根据上面的特点,可以解决问题(核心都是中序的结构特点:可以明确区分出左子树右子树的位置):
前+中=>后+层:
- 前序的第一个就是root,对应找到中序中根的位置,那么中序根前面的就是左子树,后面的就是右子树。
- 数一下左子树右子树的元素个数,对应在前序中找到左子树右子树的位置,如上图标示。
- 那么,下面对于左子树右子树又是一个全新的树,仍然按照以上规律,即在前序左子树L中,第一个元素B是root(同时也是父节点A的左节点),在前序右子树R中,第一个元素C是root(同时也是父节点A的右节点)……
- 重建出二叉树之后,后序/层序就是遍历就OK了。
后+中=>前+层:(类似上面的方法,就是后序的根节点在尾部,相应的左子树/右子树的根节点B/C在尾部,见上图所示。)
具体解决办法:
- 若是选择题,直接手写出二叉树,有了二叉树之后,什么序都秒秒钟的事。
- 若是编程题,那就要动手实现了,具体有2个思路:a. 直接递归打印各种序的排列(不用重建二叉树)。 b. 先重建出二叉树,再各种序的遍历打印。
实现:
手写:
代码实现:
直接递归打印,不用重建二叉树
前序+中序=>后序
public class PreOrderAndInOrder { /** * * @param pre_bg_index 前序数组中,开始的索引(具体到左(右)子树中,数组开始索引+长度len精确指定了某一个左(右)子树) * @param in_bg_index 中序数组中,开始的索引 * @param len 树(左(右)子树对应到数组中的长度) * @param pre_Order_Array 前序数组 * @param in_Order_Array 中序数组 (这里一直把前序中序数组当做参数,是由于在递归过程中,没有动过数组,只是动态的去其中的某些项。) */ public static void postOrderSolution(int pre_bg_index, int in_bg_index, int len, char[] pre_Order_Array, char[] in_Order_Array) { if (len == 0) return; char root = pre_Order_Array[pre_bg_index]; if (len==1){//递归出口。 System.out.print(root+" "); return; } int i = 0; while (root != in_Order_Array[in_bg_index + i]) {//找到中序根节点的位置。 i++; } //左右中,标准的后序遍历的形式。 postOrderSolution(pre_bg_index+1, in_bg_index, i, pre_Order_Array, in_Order_Array); postOrderSolution(pre_bg_index+i+1, in_bg_index+i+1, len-i-1, pre_Order_Array, in_Order_Array); System.out.print(root+" "); } public static void main(String[] args){ char[] pre_Order_Array = {'A','B','D','E','H','C','F','G','I'}; char[] in_Order_Array = {'D','B','H','E','A','F','C','G','I'}; postOrderSolution(0, 0, pre_Order_Array.length, pre_Order_Array, in_Order_Array); }}
后序+中序=>前序(与上面大体类似,就是后序的下标用于定位根节点的位置与前序不同)
public class InOrderAndPostOrder { /** * * @param post_end_index 后序数组中,结束的索引(具体到左(右)子树中,数组结束索引+长度len精确指定了某一个左(右)子树) * @param in_bg_index 中序数组中,开始的索引 * @param len 树(左(右)子树对应到数组中的长度) * @param post_Order_Array 后序数组 * @param in_Order_Array 中序数组 (这里一直把前序中序数组当做参数,是由于在递归过程中,没有动过数组,只是动态的去其中的某些项。) */ public static void preOrderSolution(int post_end_index, int in_bg_index, int len, char[] post_Order_Array, char[] in_Order_Array) { if (len == 0) return; char root = post_Order_Array[post_end_index]; if (len==1){//递归出口。 System.out.print(root+" "); return; } int i = 0; while (root != in_Order_Array[in_bg_index + i]) {//找到中序根节点的位置。 i++; } //中左右,标准的前序遍历的形式。注意左子树中后序结束的索引是从后往前减的,中间减掉的(len-i-1)是右子树对应的数组长度。 System.out.print(root+" "); preOrderSolution(post_end_index-(len-i-1)-1, in_bg_index, i, post_Order_Array, in_Order_Array); preOrderSolution(post_end_index-1, in_bg_index+i+1, len-i-1, post_Order_Array, in_Order_Array); } public static void main(String[] args){ char[] post_Order_Array = {'D','H','E','B','F','I','G','C','A'}; char[] in_Order_Array = {'D','B','H','E','A','F','C','G','I'}; preOrderSolution(post_Order_Array.length-1, 0, post_Order_Array.length, post_Order_Array, in_Order_Array); }}
重建二叉树,然后各种序遍历输出,这里以 前序+中序=>后序+层序 为例:
public class TreeNode { char val; TreeNode left; TreeNode right; public TreeNode(char val) { this.val = val; }}
public class ReConstructPreAndIn { /** * @param pre_bg_index 前序数组中,开始的索引(具体到左(右)子树中,数组开始索引+长度len精确指定了某一个左(右)子树) * @param in_bg_index 中序数组中,开始的索引 * @param len 树(左(右)子树对应到数组中的长度) * @param pre_Order_Array 前序数组 * @param in_Order_Array 中序数组 (这里一直把前序中序数组当做参数,是由于在递归过程中,没有动过数组,只是动态的去其中的某些项。) */ public static TreeNode reConstruct(int pre_bg_index, int in_bg_index, int len, char[] pre_Order_Array, char[] in_Order_Array) { if (len == 0) return null; char root = pre_Order_Array[pre_bg_index]; if (len == 1) {//递归出口。 TreeNode newNode = new TreeNode(root); return newNode; } int i = 0; while (root != in_Order_Array[in_bg_index + i]) {//找到中序根节点的位置。 i++; } TreeNode node = new TreeNode(root); node.left = reConstruct(pre_bg_index + 1, in_bg_index, i, pre_Order_Array, in_Order_Array); node.right = reConstruct(pre_bg_index + i + 1, in_bg_index + i + 1, len - i - 1, pre_Order_Array, in_Order_Array); return node; } //后序遍历 public static void postOrderTransverse(TreeNode root) { if (root == null) return; if (root.left == null && root.right == null) { System.out.print(root.val + " "); return; } postOrderTransverse(root.left); postOrderTransverse(root.right); System.out.print(root.val + " "); } //层序遍历 public static void levelOrderTransverse(TreeNode root){ Queue<TreeNode> queue = new LinkedList<>(); queue.add(root); TreeNode node; while (!queue.isEmpty()){ node = queue.peek(); System.out.print(node.val+" "); queue.poll(); if(node.left!=null) queue.add(node.left); if(node.right!=null) queue.add(node.right); } } public static void main(String[] args) { char[] pre_Order_Array = {'A', 'B', 'D', 'E', 'H', 'C', 'F', 'G', 'I'}; char[] in_Order_Array = {'D', 'B', 'H', 'E', 'A', 'F', 'C', 'G', 'I'}; TreeNode root = reConstruct(0, 0, pre_Order_Array.length, pre_Order_Array, in_Order_Array); postOrderTransverse(root); System.out.println(); levelOrderTransverse(root); }}
End
阅读全文
1 0
- 二叉树前序后序中序互推总结
- 二叉树<总结一>
- 二叉树<总结二>
- 二叉树的总结
- 二叉树算法总结
- 二叉树总结
- 二叉树题总结
- 二叉树学习总结
- 二叉树<总结一>
- 二叉树<总结二>
- 二叉树总结
- 二叉树性质总结
- 二叉树的总结
- 二叉树应用总结
- 数据结构---二叉树总结
- 二叉树总结
- 二叉树总结_legend
- 二叉树题目总结
- css 层叠性 统计权重 优先级问题
- 输入输出流概念
- 2017 ACMICPC Asia Regional Shenyang Online
- Ecplise创建一个类的时候如何自动添加作者,时间等信息
- C语言指针
- 二叉树前序后序中序互推总结
- 【单片机笔记】中颖单片机开发笔记
- centos7 mysql数据库安装
- CSDN博客积分规则和获取积分方法
- C/C++ 二级指针
- 413.Arithmetic Slices
- Diego 架构
- mysql 导入错误 /*!40101 SET NAMES utf8mb4 */;
- eclice快捷键