二叉树的深度,判断是否是平衡二叉树
求二叉树的深度:当树为空的时候,返回0,其他情况,递归返回左右子树深度较大的+1即可
//返回树深度
public static int treedeep(BinTree root){
if(root==null) return 0;
int leftlen=treedeep(root.left);
int rightlen=treedeep(root.right);
return (leftlen>rightlen)?(leftlen+1):(rightlen+1);
}
判断是否是平衡二叉树:根据求深度的基础上很容易实现如下:
//是否是AVL树
public static boolean isAVL(BinTree root){
if(root==null) return true;
int leftlen=treedeep(root.left);
int rightlen=treedeep(root.right);
if(leftlen-rightlen<-1 ||leftlen-rightlen>1)
return false;
return (isAVL(root.left)&& isAVL(root.right));
}
上面的判断是否是AVL树代码对树反复遍历,我们来进行优化,根据后序遍历的思想,在遍历一个节点之前我们就已经遍历了他的左右子树,遍历每个节点的时候记录他的深度。就可以一边遍历,一边判断每个节点是否是平衡的,只用遍历一边二叉树。
java实现代码:
package com.mytest.mymain;
class BinTree{
public int value; //
public BinTree left;
public BinTree right;
BinTree(int x) { value = x; }
}
class Refdeep{
public int deep=0;
}
public class AVLtree {
public static int deep=0;
public static void main(String[] args) {
BinTree root=new BinTree(1);
BinTree Node2=new BinTree(2);
BinTree Node3=new BinTree(3);
BinTree Node4=new BinTree(4);
//BinTree Node5=new BinTree(5);
BinTree Node6=new BinTree(6);
BinTree Node7=new BinTree(7);
BinTree Node8=new BinTree(8);
root.left=Node2;
root.right=Node3;
Node2.left=Node4;
//Node2.right=Node5;
Node3.left=Node6;
Node3.right=Node7;
Node4.left=Node8;
System.out.println(treedeep(root));
System.out.println(isAVL(root));
Refdeep refdeep=new Refdeep();
System.out.println(isAVL02(root, refdeep));
}
//返回树深度
public static int treedeep(BinTree root){
if(root==null) return 0;
int leftlen=treedeep(root.left);
int rightlen=treedeep(root.right);
return (leftlen>rightlen)?(leftlen+1):(rightlen+1);
}
//是否是AVL树
public static boolean isAVL(BinTree root){
if(root==null) return true;
int leftlen=treedeep(root.left);
int rightlen=treedeep(root.right);
if(leftlen-rightlen<-1 ||leftlen-rightlen>1)
return false;
return (isAVL(root.left)&& isAVL(root.right));
}
//是否是AVL树:优化,节点只遍历一遍,按照后序遍历的思想,进行判断。
//我们用后序遍历的方式遍历二叉树的每一个结点,在遍历到一个结点之前我们已经遍历了它的左右子树。
//只要在遍历每个结点的时候记录它的深度(某一结点的深度等于它到叶节点的路径的长度),我们就可以一边遍历一边判断每个结点是不是平衡的
public static boolean isAVL02(BinTree root, Refdeep refdeep){ //java是值传递 引用传递?思考
if(root == null){
refdeep.deep = 0;
return true;
}
Refdeep refdeepleft=new Refdeep();
Refdeep refdeepright=new Refdeep();
if(isAVL02(root.left,refdeepleft) && isAVL02(root.right,refdeepright)){ //A && B 当A不满足的时候,B不执行。
int diff = refdeepleft.deep-refdeepright.deep;
if(diff <= 1 && diff >= -1){
refdeep.deep = 1+(refdeepleft.deep > refdeepright.deep?refdeepleft.deep : refdeepright.deep);
return true;
}
}
return false;
}
}
备注:其中,由于java不像C++,有引用传递 &deep,即可函数调用之间可以共享一个变量,这里引入一个类用于转值传递为引用传递。更好实现方式和正确性有待进一步考证,考虑单例模式啊,静态变量啊之类的。
牛客网在线编程–剑指offer中对应的求树深度和判断平衡二叉树题目此优化代码通过。
牛客网在线编程:剑指offerjava代码通过:
求树的深度:
public class Solution {
public int TreeDepth(TreeNode root) {
if(root==null) return 0;
int leftlen=TreeDepth(root.left);
int rightlen=TreeDepth(root.right);
return leftlen>rightlen?(leftlen+1):(rightlen+1);
}
}
判断是否是平衡二叉树:
class Refdeep{
public int deep=0;
}
public class Solution {
public boolean IsBalanced_Solution(TreeNode root) {
Refdeep refdeep=new Refdeep();
return IsBalanced_Solution2(root,refdeep);
}
public boolean IsBalanced_Solution2(TreeNode root,Refdeep refdeep) {
if(root == null){
refdeep.deep = 0;
return true;
}
Refdeep refdeepleft=new Refdeep();
Refdeep refdeepright=new Refdeep();
if(IsBalanced_Solution2(root.left,refdeepleft) && IsBalanced_Solution2(root.right,refdeepright)){
int diff = refdeepleft.deep-refdeepright.deep;
if(diff <= 1 && diff >= -1){
refdeep.deep = 1+(refdeepleft.deep > refdeepright.deep?refdeepleft.deep : refdeepright.deep);
return true;
}
}
return false;
}
}