二叉树的深度

  • 题目:输入一颗二叉树的根,求该树的深度。从根节点到叶子节点一次进过的节点形成的一条路径,最长的路径的长度为树的深度。
  • 如下图中二叉树的额深度4,因为从根节点A到叶子节点的路径中有4个节点A B E J

  • 问题中定义了一种树深度的计算规则,我们根据这个定义去得到树所有的路径,也就得到了最长的额路径。在我们之前的文章:数据结构与算法–面试必问AVL树原理及实现文章中,我们对二叉搜索树的具体实现方案有详细的说明,其中二叉搜索树平衡条件是左右子树的高度差不能超过1 ,和我们当前要求是一致的,我们借鉴其中高度求值的思路
  • 分析
    • 二叉树还是递归的思路,既然我们需要求高度差
    • 分别递归求左右子树的高度,在求解
    • 同二叉树的后续遍历一样递归,只不是现在将遍历元素值,变为现在遍历高度并累加
    • 递归思路,按最简单的节点分析,当只有一个左右子树,那么递归到left 高度0, 递归到right 高度0
    • 那么此时根节点高度 height= Math.max(left + right) + 1
  • 经如上分析有如下代码
/*** 求二叉树的深度* @author liaojiamin* @Date:Created in 17:43 2021/6/24*/
public class BinaryDepth {public static void main(String[] args) {BinaryNode node1 = new BinaryNode(null, null, null);BinarySearchTree tree1 = new BinarySearchTree();Random random = new Random();int[] array = new int[]{1,27,37,19,514,216,118,320,426,228};for (int i = 0; i < array.length; i++) {node1 = tree1.insert(Integer.valueOf(random.nextInt(20)), node1);}System.out.println(depthBinary(node1));tree1.printTree(node1);}
/*** 递归方式求解,*  左节点为空则,左高度为left = 0,总高度为 left + 1*  右节点为空则,右高度为right = 0,总高度为 right + 1*  递归到子节点,赋值left= 0,right = 0,接着一层一层递归上到根节点。* */public static Integer depthBinary(BinaryNode tree){if(tree == null){return 0;}int left = depthBinary(tree.getLeft());int right = depthBinary(tree.getRight());return left > right ? left + 1 : right + 1;}
}

变种题型-求平衡二叉树

  • 题目:输入一颗二叉树的根,判断该树是否平衡二叉树。如果某二叉树中任意左右节点的树深度不超过1 ,那么他就是一颗平衡二叉树。
  • 还是在刚才二叉搜索树的文中,我们求高度的目的就是需要再平衡二叉树,使得经过修改的二叉树能够达到二叉搜索树的结构特性。既然在以上方法中我们得到了高度,那么可以在逻辑上修改就能求解本问题
  • 分析:
    • 通上题中,分别递归求解left, right
    • 得到left, right高度,求差值 > 1 ,则不是平衡
  • 如上分析有如下代码:
/*** 求二叉树的深度* @author liaojiamin* @Date:Created in 17:43 2021/6/24*/
public class BinaryDepth {public static void main(String[] args) {BinaryNode node1 = new BinaryNode(null, null, null);BinarySearchTree tree1 = new BinarySearchTree();Random random = new Random();int[] array = new int[]{1,27,37,19,514,216,118,320,426,228};for (int i = 0; i < array.length; i++) {node1 = tree1.insert(Integer.valueOf(random.nextInt(20)), node1);}System.out.println(validateBalancedTree(node1));tree1.printTree(node1);}/*** 一棵二叉树中所有节点对应的左右子树高度差不超过1 ,那么说明这棵树是平衡二叉树* 递归判断是否平衡树* */public static boolean validateBalancedTree(BinaryNode tree){if(tree == null){return true;}int left = depthBinary(tree.getLeft());int right = depthBinary(tree.getRight());int diff = Math.abs(left - right);if(diff > 1){return false;}return validateBalancedTree(tree.getLeft()) && validateBalancedTree(tree.getRight());}/*** 递归方式求解,*  左节点为空则,左高度为left = 0,总高度为 left + 1*  右节点为空则,右高度为right = 0,总高度为 right + 1*  递归到子节点,赋值left= 0,right = 0,接着一层一层递归上到根节点。* */public static Integer depthBinary(BinaryNode tree){if(tree == null){return 0;}int left = depthBinary(tree.getLeft());int right = depthBinary(tree.getRight());return left > right ? left + 1 : right + 1;}
}
  • 以上代码比较简单,但是存在问题是节点会被重复遍历,当遍历第二层节点 B,C时候,会遍历H I J节点,同样 遍历D,E F G时候还是会重复遍历H I J 节点,类似斐波那契数量的递归求解一样,重复的遍历会时间复杂度指数级增长,当树高度越大,重复遍历的次数越多。我们需要找到更优方案

每个节点遍历一次解法

  • 我们之前是为了求深度,才直接递归左右节点,然后在判断,既然我们都遍历了求出了深度,那么能不能同时标记每一个节点的深度呢
  • 分析
    • 还是按刚才思路,分别遍历左右子树求高度,我们还是按最简单的元素来分析递归的情况
    • 当左右子树都只有一个节点,遍历左子树,left = 1, 遍历右子树 right = 1
    • 此时不同的点我们更新当前根节点的高度height = Math.max(left,right) + 1
    • 依次递归到根节点
    • 以上思路还是二叉树的后续遍历的思想,左右根,一边遍历,一边计算高度,一边更新节点高度信息
    • 更新完根的高度后,在判断是否满足 left - right > 1,放回对应值,以跳出递归
  • 如是哪个分析有如下代码
/*** 求二叉树的深度* @author liaojiamin* @Date:Created in 17:43 2021/6/24*/
public class BinaryDepth {public static void main(String[] args) {BinaryNode node1 = new BinaryNode(null, null, null);BinarySearchTree tree1 = new BinarySearchTree();Random random = new Random();int[] array = new int[]{1,27,37,19,514,216,118,320,426,228};for (int i = 0; i < array.length; i++) {node1 = tree1.insert(Integer.valueOf(random.nextInt(20)), node1);}System.out.println(validateBalancedTreeHeight(node1));tree1.printTree(node1);}/*** 直接后序遍历,同时标记深度* */public static boolean validateBalancedTreeHeight(BinaryNode tree){if(tree == null){return true;}boolean left = validateBalancedTreeHeight(tree.getLeft());boolean right = validateBalancedTreeHeight(tree.getRight());int leftHeight = tree.getLeft()!= null ? tree.getLeft().getHeight(): 0;int rightHeight = tree.getRight() != null ? tree.getRight().getHeight() : 0;tree.setHeight(1 + Math.max(leftHeight, rightHeight));if(left && right){int diff = Math.abs(leftHeight - rightHeight);if(diff > 1){return false;}else {return true;}}return false;}}
  • 以上方法后续遍历的方式遍历整个二叉树,遍历同时求深度,判断平衡,当遍历到树根,也就得树是否平衡的二叉树。

上一篇:数据结构与算法–数字在排序数组中出现次数
下一篇:数据结构与算法–数组中出一次的数字

数据结构与算法--二叉树的深度问题相关推荐

  1. 数据结构与算法--二叉树第k个大的节点

    二叉树第k个大的节点 二叉树文章列表: 数据结构与算法–面试必问AVL树原理及实现 数据结构与算法–二叉树的深度问题 数据结构与算法–二叉堆(最大堆,最小堆)实现及原理 数据结构与算法–二叉查找树转顺 ...

  2. 数据结构与算法-- 二叉树中和为某一值的路径

    二叉树中和为某一值的路径 题目:输入一颗二叉树和一个整数,打印出二叉树中节点值的和为给定值的所有路径.从树的根节点开始往下一只到叶子节点所经过的节点形成一条路径. 我们用二叉树节点的定义沿用之前文章中 ...

  3. 数据结构与算法-- 二叉树后续遍历序列校验

    二叉树后续遍历序列校验 题目:输入一个整数数组,判断改数组是否是某个二叉搜索树的后续遍历结果,如果是返回true否则false,假设输入数组的任意两个数字不相同. 例如输入{5,7,6,9,11,10 ...

  4. javascript数据结构与算法--二叉树遍历(中序)

    javascript数据结构与算法--二叉树遍历(中序) 中序遍历按照节点上的键值,以升序访问BST上的所有节点 代码如下: /**二叉树中,相对较小的值保存在左节点上,较大的值保存在右节点中*** ...

  5. 数据结构与算法-二叉树(java描述)

    一.概述 1.1.树的概念 树状图是一种数据结构,它是由n(n>=1)个有限节点组成一个具有层次关系的集合.把它叫做"树"是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而 ...

  6. 数据结构与算法 -- 二叉树 ADT

    树的类型有很多,这里我们只讲二叉树. 一.二叉树的基本概念 1.什么是二叉树 在计算机科中,二叉树是每个节点最多有两个子树的树结构.通常子树被称作"左子树"和"右子树&q ...

  7. 数据结构与算法--二叉树实现原理

    二叉树 二叉树(binary tree)是一棵树,其中每个节点都不能有多于两个的子节点 二叉树的一个性质是一颗平均二叉树的深度要比节点个数N小得多(重点),对二叉树的分析得出其平均深度为O(N\sqr ...

  8. 数据结构与算法——二叉树

    二叉树 一.树的定义: 二.二叉树的概念 2.1二叉树的定义: 2.2二叉树的性质 2.3 二叉树的存储表示 2.4.二叉树的遍历(Binary Tree Traversal) 递归实现先.中.后序遍 ...

  9. [PHP]算法- 二叉树的深度的PHP实现

    二叉树的深度: 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度.思路: 1.非递归层序遍历 2.使用辅助队列,根结点先入队列 3 ...

最新文章

  1. 计算机系统唯一能识别的不需要翻译,计算机习题答案及解析ban.doc
  2. Exploiting the Syntax-Model Consistency for Neural Relation Extraction-学习笔记
  3. linux内核中的循环缓冲区
  4. Sphinx语音识别学习记录 (五)-错误调试
  5. ios main函数之前的操作_添加函数在ARM在进入main函数之前
  6. MATLAB免疫算法求解超市物流配送中心选址问题实例
  7. 简历模板80套.zip
  8. keytool条目_keytool常用命令
  9. 冰点还原精灵V8.37.020系统还原软件
  10. 川大《计算机应用基础》第二次作业,川大16秋《计算机应用基础》第二次作业答案.pdf...
  11. 从校园到职场 - 什么是职场经验
  12. android 无法添加帐户,android - Android SecurityException:uid xxxxx无法显式添加帐户 - 堆栈内存溢出...
  13. 信息泄露能算高危漏洞吗
  14. 来!学逆向都想的手游防护(下篇更新破解)
  15. 毕业论文降重的有关经验
  16. PG虚拟文件描述符(VFD)机制——封装的文件接口:postgresql-8.4.1/src/backend/storage/file/fd.c
  17. 768位RSA算法遭破解,1024位目前安全
  18. /tmp/cc8TKj9o.s: Assembler messages
  19. 1983年美国制定的c语言标准,C语言的发展历史
  20. ip广播系统服务器设备,校园IP网络广播设备都有哪些?数字IP广播系统如何配置-航天广电软件...

热门文章

  1. C和指针之memmove函数 memcpy函数 strcspn函数 strspn函数 strrstr函数实现
  2. Android插件化开发之动态加载技术系列索引
  3. Android之用HttpURLConnection参数以XML形式封装的部分关键代码
  4. javascript 高级程序设计_重读《JavaScript高级程序设计》
  5. tomcat出现5个using_当猫咪出现这5个迹象,主人就要给猫咪换猫粮了
  6. 好心帮男朋友洗衣服,他却要分手??
  7. 在中国,有这样一些村落
  8. 揭秘神仙高校的课堂!网友跪了:这就是差距啊!
  9. 为什么现在老师这么难,值得大家深思
  10. linux实时进程优先级rt,Linux实时性- PREEMPT_RT实时抢占实现