剑指offer面试题39:二叉树深度与平衡二叉树
来源:互联网 发布:8080端口外网访问 编辑:程序博客网 时间:2024/04/29 03:12
题目一:二叉树深度
程序运行结果:
输入一颗二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为数的深度
题目二:平衡二叉树
输入一颗二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一颗平衡二叉树。例如,图中即为一颗平衡二叉树。
算法分析:
算法1.每个节点只遍历一次
如果我们用后续遍历的方式遍历二叉树的每一个节点,在遍历到一个节点之前我们就已经遍历了它的左右子树。只要在遍历每个节点的时候记录他的深度(某一节点的深度等于它到叶节点的长度),我们就可以一边遍历一遍判断每个节点是不是平衡的。
算法2.重复遍历
在遍历树的每个节点的时候,调用函数TreeDepth得到他的左右树的深度。如果每个节点的左右子树的深度相差都不超过1,按照定义则它就是一棵平衡二叉树。但该算法的某些节点会被重复遍历多次,时间效率不高。
遇到问题:
在算法1中,定义depth和left,right变量不能使用整型变量,而要使用只保存一个数据的一维数组,使用整形变量后,在递归调用一下语句时:
int left = 0; //不能使用变量,应该使用数组保存
int right = 0;
int diff = left- right;
System.out.println("left= " + left+",right="+right);
if(diff <= 1 && diff >= -1){
depth = 1 + (left > right ? left:right);
System.out.println("depth=" + depth);
return true;
} 就会遇到问题,每次都会将left和right的值重新赋值为0,而采用数组时,虽然有以下语句:
int[] left = new int[1];
int[] right = new int[1];
if(IsBalancedHelper(root.leftNode, left)&& IsBalancedHelper(root.rightNode, right)){
int diff = left[0] - right[0];
System.out.println("left[0] = " + left[0] + ",right[0]=" + right[0]);
if(diff <= 1 && diff >= -1){
depth[0] = 1 + (left[0] > right[0] ? left[0]:right[0]);
System.out.println("depth=" + depth[0]); //此处depth值依次为r6,r4,r5,r2,r3的深度
return true;
} 但根据Java的“引用”规则,left[]和right[]数组中每次都会保存的是递归调用后depth的值,即为
left[0] = 0,right[0]=0
depth=1
left[0] = 0,right[0]=1
depth=2
left[0] = 0,right[0]=0
depth=1
left[0] = 2,right[0]=1
depth=3
left[0] = 0,right[0]=0
depth=1
left[0] = 3,right[0]=1 所以,在递归调用时,要注意变量的定义,防止在每次递归调用时重新刷新原有值。
生成二叉树的方法:
class TreeNode{
int val;
TreeNode leftNode = null;
TreeNode rightNode = null;
public TreeNode(int val){
this.val = val;
}
} 先定义一个二叉树类,然后 使用下面方法对二叉树进行赋值。
/*
1
/ \
2 3
/ \
4 5
\
6
*/
TreeNode r1 = new TreeNode(1);
TreeNode r2 = new TreeNode(2);
TreeNode r3 = new TreeNode(3);
TreeNode r4 = new TreeNode(4);
TreeNode r5 = new TreeNode(5);
TreeNode r6 = new TreeNode(6);
r1.leftNode = r2;
r1.rightNode = r3;
r2.leftNode = r4;
r2.rightNode = r5;
r4.rightNode = r6; 算法源程序:
/************************************************************** * Copyright (c) 2016, * All rights reserved. * 版 本 号:v1.0 * 题目描述:平衡二叉树* 输入一颗二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过1,* 那么它就是一颗平衡二叉树。例如,图中即为一颗平衡二叉树。* 例如:下面二叉树打印出 1,2,3,4,5,6.* 1 * / \ * 2 3 * / \ * 4 5 * \* 6* 输入描述:无* 程序输出: 见运行后结果* 问题分析: * 算法描述: 如果我们用后续遍历的方式遍历二叉树的每一个节点,在遍历到一个节点之前我们就已经遍历了它的左右子树。* 只要在遍历每个节点的时候记录他的深度(某一节点的深度等于它到叶节点的长度),我们就可以一边遍历一遍判断每个节点是不是平衡的。* 算法2.重复遍历*在遍历树的每个节点的时候,调用函数TreeDepth得到他的左右树的深度。如果每个节点的左右子树的深度相差都不超过1,*按照定义则它就是一棵平衡二叉树。但该算法的某些节点会被重复遍历多次,时间效率不高。* 完成日期:2016-09-26***************************************************************/package org.marsguo.offerproject39;//import org.marsguo.offerproject.TreeNode;class TreeNode{int val;TreeNode leftNode = null;TreeNode rightNode = null;public TreeNode(int val){this.val = val;}}/*算法1.较为复杂*/class FindBalanceTree{public static boolean isBalanced2(TreeNode root){int[] depth = new int[1];//int depth = 0;不能使用变量,应该使用数组保存return IsBalancedHelper(root,depth);}public static boolean IsBalancedHelper(TreeNode root,int[] depth){if(root == null){//depth = 0;depth[0] = 0;return true;}int[] left = new int[1];int[] right = new int[1];//System.out.println("left=" + left[0] + ",right= " + right[0]);//int left = 0;//不能使用变量,应该使用数组保存//int right = 0;if(IsBalancedHelper(root.leftNode, left)&& IsBalancedHelper(root.rightNode, right)){int diff = left[0] - right[0];//System.out.println("left[0] = " + left[0] + ",right[0]=" + right[0]);if(diff <= 1 && diff >= -1){ depth[0] = 1 + (left[0] > right[0] ? left[0]:right[0]); System.out.println("depth=" + depth[0]);//此处depth值依次为r6,r4,r5,r2,r3的深度return true;}//int diff = left- right;//System.out.println("left= " + left+",right="+right);//if(diff <= 1 && diff >= -1){// depth = 1 + (left > right ? left:right);// System.out.println("depth=" + depth);//return true;//}}return false;}}/*算法2.简单,但一个节点会重复遍历多次*/class SolutionMethod2{public boolean isBalancedSolution(TreeNode root){if(root == null)return true;int left = getDepth(root.leftNode);//此处得到的是r2的深度,不是r1;r2深度为3int right = getDepth(root.rightNode);//此处得到的是r3深度,不是r1;r3深度为1System.out.println("算法2:left= " + left + "right= " + right);System.out.println("算法2:left-right= " + (left - right));return (Math.abs(left-right) >1)? false:true;//Math.abs() 取绝对值,}public int getDepth(TreeNode root){if(root == null)return 0;int left = getDepth(root.leftNode) + 1;int right = getDepth(root.rightNode) + 1;/*此处输出的left和right值依次为:r6,r4,r5,r2,r3的深度*/System.out.println("left = " + left + ", right = " + right);return left > right? left:right;}}public class BalanceTree {public static void main(String[] args){/* 1 / \ 2 3 / \ 4 5 \ 6 */TreeNode r1 = new TreeNode(1); TreeNode r2 = new TreeNode(2);TreeNode r3 = new TreeNode(3);TreeNode r4 = new TreeNode(4);TreeNode r5 = new TreeNode(5);TreeNode r6 = new TreeNode(6);r1.leftNode = r2;r1.rightNode = r3;r2.leftNode = r4;r2.rightNode = r5;r4.rightNode = r6;/*1 / \ 2 3 / \ \4 5 6 \ 7 */TreeNode r21 = new TreeNode(1);TreeNode r22 = new TreeNode(2);TreeNode r23 = new TreeNode(3);TreeNode r24 = new TreeNode(4);TreeNode r25 = new TreeNode(5);TreeNode r26 = new TreeNode(6);TreeNode r27 = new TreeNode(7);r21.leftNode = r22;r21.rightNode = r23;r22.leftNode = r24;r22.rightNode = r25;r25.rightNode = r27;r23.rightNode = r26;//FindBalanceTree findbalancetree = new FindBalanceTree();//调用静态方法,所以不用生成对象,直接采用类名调用System.out.println("采用算法1的输出:" + FindBalanceTree.isBalanced2(r1));SolutionMethod2 solution2 = new SolutionMethod2();System.out.println("采用算法2的输出:" + solution2.isBalancedSolution(r1));System.out.println("第二棵树采用算法1的输出:" + FindBalanceTree.isBalanced2(r21));SolutionMethod2 solution22 = new SolutionMethod2();System.out.println("第二棵树采用算法2的输出:" + solution22.isBalancedSolution(r21));}}
程序运行结果:
0 0
- 剑指offer面试题39:二叉树深度与平衡二叉树
- 剑指offer 面试题39 求二叉树深度|判断是否为平衡二叉树
- 剑指offer 面试题39—二叉树的深度vs平衡二叉树判断
- 剑指offer面试题39:二叉树深度以及判断平衡二叉树
- 《剑指Offer》面试题:平衡二叉树
- 剑指offer面试题 39 二叉树的深度和判断是不是平衡树
- 【剑指Offer】:面试题39:平衡二叉树
- 【面试题】剑指Offer-39-求二叉树的深度和判断一颗树是否为平衡二叉树
- 剑指Offer面试题39二叉树的深度(以及判断平衡二叉树),面试题40数组中只出现一次的数字
- [剑指offer][面试题39]二叉树的深度
- 【剑指offer】面试题39:二叉树的深度
- 剑指Offer:面试题39 二叉树的深度
- 【剑指Offer学习】【面试题39:二叉树的深度】
- 剑指offer-面试题39:二叉树的深度
- 剑指Offer----面试题39(1):二叉树的深度
- 剑指offer--面试题39:二叉树的深度
- 【剑指offer】面试题39-二叉树的深度
- 剑指Offer-面试题39-二叉树的深度
- 监听器
- mac下编译安装php7时报ld: symbol(s) not found for architecture x86_64的解决方法
- HDU 2571 命运 DP .
- 2016.09.26
- Nginx支持热部署
- 剑指offer面试题39:二叉树深度与平衡二叉树
- C语言输出
- Qt: 获取当前电脑中包含的数据库驱动
- 浙江大学公开课-数据结构第一讲笔记
- 【Linux4.1.12源码分析】IP层报文发送之ip_output
- JavaScript
- Days 21 Notification & BroadcastReceiver
- Android的数据存储——存储键值对,SharedPreferences
- hdu 1241 Oil Deposits