程序员面试经典--检查二叉树是否平衡

4.1问题:

实现一个函数,检查二叉树是否平衡。在这个问题中,平衡树的定义如下:任意一个结点,其两棵子树的高度差不超过1.

思考:

可以直接递归访问整颗树,计算每个结点的两棵子树的高度。

	public static int getHeight(Node root){ //获取二叉树的深度
		if(root == null){
			return 0;//终止条件
		}
		return Math.max(getHeight(root.leftChild),getHeight(root.rightChild))+1;
	}
	
	public static boolean isBalance(Node root){
		if(root == null){
			return true;//终止条件
		}
		int heighDiff= getHeight(root.leftChild)-getHeight(root.rightChild);
		if(Math.abs(heighDiff)>1){
			return false;
		}
		else{
			return isBalance(root.leftChild)&&isBalance(root.rightChild);
		}
	}
虽然可行,但效率不高,这段代码会递归访问每个结点的整棵子树。也就是说,getHeight会被反复调用计算同一个结点的高度。因此,这个算法时间复杂度为O(NlogN)。

看下面一段改进的程序:

public static int checkHeight(Node root){
		if(root == null){
			return 0;//高度为0
		}
		
		//检查左子树是否平衡
		int leftHeight = checkHeight(root.leftChild);
		if(leftHeight == -1){
			return -1;//不平衡
		}
		//检查右子树是否平衡
		int rightHeight = checkHeight(root.rightChild);
		if(rightHeight == -1){
			return -1;//不平衡
		}
		
		//检查当前节点是否平衡
		int heightDiff = leftHeight - rightHeight;
		if(Math.abs(heightDiff) > 1){
			return -1;//不平衡
		}else{
			return Math.max(leftHeight,rightHeight) + 1;
		}
	}
	
	public static boolean isBalance1(Node root){
		if(checkHeight(root) == -1){
			return false;
		}else{
			return true;
		}
	}
改进过的算法会从根结点递归向下检查每棵子树的高度。我们会通过checkHeight方法,以递归的方式获取每个结点的左右子树的高度。若子树是平衡的,则checkHeight返回-1.checkHeight会立即中断,并返回-1.

这段代码需要的时间复杂度为O(N),空间复杂度为O(H),H为树的高度。





你可能感兴趣的:(程序员面试经典--检查二叉树是否平衡)