二叉树的深度
题目:输入一颗二叉树的根,求该树的深度。从根节点到叶子节点一次进过的节点形成的一条路径,最长的路径的长度为树的深度。 如下图中二叉树的额深度4,因为从根节点A到叶子节点的路径中有4个节点A B E J
问题中定义了一种树深度的计算规则,我们根据这个定义去得到树所有的路径,也就得到了最长的额路径。在我们之前的文章:数据结构与算法–面试必问AVL树原理及实现 文章中,我们对二叉搜索树的具体实现方案有详细的说明,其中二叉搜索树平衡条件是左右子树的高度差不能超过1 ,和我们当前要求是一致的,我们借鉴其中高度求值的思路 分析
二叉树还是递归的思路,既然我们需要求高度差 分别递归求左右子树的高度,在求解 同二叉树的后续遍历一样递归,只不是现在将遍历元素值,变为现在遍历高度并累加 递归思路,按最简单的节点分析,当只有一个左右子树,那么递归到left 高度0, 递归到right 高度0 那么此时根节点高度 height= Math.max(left + right) + 1 经如上分析有如下代码
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) ;
}
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 ,则不是平衡 如上分析有如下代码:
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) ;
}
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 ( ) ) ;
}
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,放回对应值,以跳出递归 如是哪个分析有如下代码
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 ;
}
}
以上方法后续遍历的方式遍历整个二叉树,遍历同时求深度,判断平衡,当遍历到树根,也就得树是否平衡的二叉树。
上一篇:数据结构与算法–数字在排序数组中出现次数 下一篇:数据结构与算法–数组中出一次的数字