Java——从前序与中序遍历序列构造二叉树
文章目录
- 前言
- 一、已知前序和中序构造二叉树,并层次输出
- 二、问题分析
- 1.构造二叉树
- 2.层次遍历二叉树
- 三、总结
前言
算法分析——分治法
一、已知前序和中序构造二叉树,并层次输出
二、问题分析
首先我们获取到的信息为一个前序遍历的数组和一个中序遍历的数组。前序遍历的顺序为 根左右 ,中序遍历的顺序为 左根右 。
1.构造二叉树
我们首先应该找到树的根节点,也就是前序遍历的第一个数,并在中序遍历中标记出根节点的位置,随后便可知道左子树和右子树的节点个数
// 根节点值是前序遍历的第一个TreeNode root = new TreeNode(preorder[pleft]);// 中序遍历第一个为起始点int middle = ileft;// 左子树节点长度int len = 0;// 找到中序遍历中的根节点位置记为middlefor (; middle < inorder.length; middle++) {if (inorder[middle] == preorder[pleft]) {break;}// 计算左子树节点长度lenlen++;
随后我们就可以通过递归调用求解出左右子树
提示:
[ 根节点, [左子树的前序遍历结果], [右子树的前序遍历结果] ]
[ [左子树的中序遍历结果], 根节点, [右子树的中序遍历结果] ]
// 递归调用求解左右子树// 左子树:前序遍历为根后一个到根加左子树长度,中序遍历为第一个到根节点位置前一个root.left = buildtree(preorder, pleft + 1, pleft + len, inorder, ileft, middle - 1);// 右子树:前序遍历为左子树后一个到最后一个,中序为根节点后一个到最后一个root.right = buildtree(preorder, pleft + len + 1, pright, inorder, middle + 1, iright);
这样,我们就通过递归的方法成功构建出了一颗二叉树。这时我们就应当考虑如何通过层次遍历输出这颗二叉树。
2.层次遍历二叉树
我们通过层次遍历二叉树的时候,需要用到 队列 的数据结构。利用队列先进先出的原则,将二叉树元素依次存进List集合中
- 先将二叉树的根节点通过**offer()**方法添加进队尾。1
- 队列非空时,将队列中的头元素取出,并将值存进 List 集合中
- 当这个头元素对应的左子节点非空时,将该左子节点添加进队列;右子节点同理
- 当队列为空时,循环结束
// 定义一个队列用于层次遍历二叉树Queue<BuildTree1.TreeNode> queue = new LinkedList<>();queue.offer(root);// offer方法表示添加元素到队尾while (!queue.isEmpty()) {BuildTree1.TreeNode temp = queue.poll();// poll方法删除队头元素result.add(temp.val);if (temp.left != null) {queue.offer(temp.left);}if (temp.right != null) {queue.offer(temp.right);}}
三、总结
这道题目比较简单,应熟悉掌握树的数据结构逻辑
代码及运行结果:
package day1;import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Scanner;public class BuildTree1 {public static class TreeNode {int val;TreeNode left;TreeNode right;TreeNode(int x) {val = x;}}// 传入前序和中序遍历public static TreeNode buildTree(int[] preorder, int[] inorder) {if (preorder == null || inorder == null) {return null;}// 非空,则开始还原二叉树return buildtree(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);}// 还原二叉树public static TreeNode buildtree(int[] preorder, int pleft, int pright, int[] inorder, int ileft, int iright) {if (pleft > pright || ileft > iright) {return null;}// 根节点值是前序遍历的第一个TreeNode root = new TreeNode(preorder[pleft]);// 中序遍历第一个为起始点int middle = ileft;// 左子树节点长度int len = 0;// 找到中序遍历中的根节点位置记为middlefor (; middle < inorder.length; middle++) {if (inorder[middle] == preorder[pleft]) {break;}// 计算左子树节点长度lenlen++;}// 递归调用求解左右子树// 左子树:前序遍历为根后一个到根加左子树长度,中序遍历为第一个到根节点位置前一个root.left = buildtree(preorder, pleft + 1, pleft + len, inorder, ileft, middle - 1);// 右子树:前序遍历为左子树后一个到最后一个,中序为根节点后一个到最后一个root.right = buildtree(preorder, pleft + len + 1, pright, inorder, middle + 1, iright);return root;}public static void cengci(TreeNode root, List<Integer> result) {// 确定终止条件if (root == null)return;else {// 定义一个队列用于层次遍历二叉树Queue<BuildTree1.TreeNode> queue = new LinkedList<>();queue.offer(root);// offer方法表示添加元素到队尾while (!queue.isEmpty()) {BuildTree1.TreeNode temp = queue.poll();// poll方法删除队头元素result.add(temp.val);if (temp.left != null) {queue.offer(temp.left);}if (temp.right != null) {queue.offer(temp.right);}}}}public static List<Integer> cengciTraversal(TreeNode root) {List<Integer> list = new ArrayList<Integer>();cengci(root, list);return list;}public static void main(String[] args) {System.out.println("输入前序遍历");Scanner sc1 = new Scanner(System.in);String str1 = sc1.next().toString();String[] s1 = str1.split(",");int[] qian = new int[s1.length];for (int i = 0; i < qian.length; i++) {qian[i] = Integer.parseInt(s1[i]);}System.out.println("输入中序遍历");Scanner sc2 = new Scanner(System.in);String str2 = sc2.next().toString();String[] s2 = str2.split(",");int[] zhong = new int[s2.length];for (int i = 0; i < zhong.length; i++) {zhong[i] = Integer.parseInt(s2[i]);}sc1.close();sc2.close();BuildTree1 buildTree1 = new BuildTree1();TreeNode r = buildTree1.buildTree(qian, zhong);System.out.println(cengciTraversal(r));}
}
这里答主留下一个疑问,如何将空节点表述出来,可以在评论区讨论一下
这里不推荐使用 add()方法 ↩︎
Java——从前序与中序遍历序列构造二叉树相关推荐
- [Leedcode][JAVA][第105题][从前序与中序遍历序列构造二叉树][栈][递归][二叉树]
[问题描述][中等] 根据一棵树的前序遍历与中序遍历构造二叉树.注意: 你可以假设树中没有重复的元素.例如,给出前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = ...
- 【LeetCode】【HOT】105. 从前序与中序遍历序列构造二叉树(哈希表+递归)
[LeetCode][HOT]105. 从前序与中序遍历序列构造二叉树 文章目录 [LeetCode][HOT]105. 从前序与中序遍历序列构造二叉树 package hot;import java ...
- 刷题记录8---验证二叉搜索树+二叉树的层序遍历+从前序与中序遍历序列构造二叉树+二叉树展开为链表+二叉树的最近公共祖先
前言 所有题目均来自力扣题库中的hot 100,之所以要记录在这里,只是方便后续复习 98.验证二叉搜索树 题目: 给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树. 有效 二叉搜 ...
- 【LeetCode系列】从中序与后序遍历序列构造二叉树 从前序与中序遍历序列构造二叉树...
关注上方"深度学习技术前沿",选择"星标公众号", 资源干货,第一时间送达! 105. 从前序与中序遍历序列构造二叉树 根据一棵树的前序遍历与中序遍历构造二叉树 ...
- 105从前序与中序遍历序列构造二叉树 106 从中序与后序遍历序列构造二叉树 (递归 + 哈希)
引言 这两道题主要是考察二叉树遍历的掌握,即由前序和中序推出原二叉树,由后序和中序推出原二叉树,这里先来说一下推导过程: 前序和中序 知道前序遍历和中序遍历,如何推原二叉树?(直接是结论,可以自行推导 ...
- 二叉树 中序遍历 python_LeetCode 105 树 从前序与中序遍历序列构造二叉树(Medium)
17(105) 从前序与中序遍历序列构造二叉树(Medium) 描述 根据一棵树的前序遍历与中序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 示例 例如,给出前序遍历 preorder = ...
- 二叉树 中序遍历 python_leetcode No.105 从前序与中序遍历序列构造二叉树
题目链接: 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)leetcode-cn.com 题目描述: 根据一棵树的前序遍历与中序遍历构造二叉树,可以假设树中没有重复的元素. 示例: 前 ...
- 找树左下角的值+路径总和+从前序和中序遍历序列构造二叉树(day18*)
这篇可以主要关注一下如何确定递归时是否需要返回值. LC513. 找树左下角的值 给定一个二叉树的根节点,请找出该二叉树的 最底层最左边 节点的值. 思路1 层序遍历 class Solution:d ...
- 【必拿下系列】106. 从中序与后序遍历序列构造二叉树105从前序与中序遍历序列构造二叉树
两题各自的链接放这里了: 链接: 106 链接: 105 106.从中序与后序遍历序列构造二叉树 如果你是不知道理论的,那就得仔细分析了, 举个例子: 输入:inorder = [9,3,15,20, ...
最新文章
- 清华大学王建民:在大数据的思维下,人人都是冰冷的数据包?
- C# mongodb 类库
- Linux 实时流量监测(iptraf中文图解)
- 【编程题】简单的四则运算
- LVM管理-元数据及分区表的恢复
- java 统计数字个数_统计数字问题(Java)
- \r,\n,\r\n
- 仪表盘怎么调 铃木uy125摩托车_平时市区骑行,摩托车链条多久保养一次?
- 马斯克:我上大学时就想创立电动汽车公司
- MySQL 语句使用到的关键字 函数 记录
- 分层图最短路【bzoj2763】: [JLOI2011]飞行路线
- 软件压力测试报告要怎么写,如何做接口压力测试?压力测试报告应该包含哪些结果?...
- 使用ExtendSim指导全球大流行爆发期间的关键决策
- 终于知道什么叫BSS段
- 四元数和旋转轴及旋转角度之间的转换理解实例
- 金融网络安全和反欺诈方法论,金融新兴技术成熟度几何?
- 感恩节快到了 Thanksgiving is coming,愿所有人健康平安!
- jsp预加载转圈_30种CSS3炫酷页面预加载loading动画特效(推荐)
- springboot使用kafka发送消息,消息过大报错
- 采用COMSOL Multiphysics软件对高灵敏度光纤压力传感器进行仿真