1. 程式人生 > >#資料結構與演算法學習筆記#劍指Offer35:是否平衡二叉樹/AVL樹 + 測試用例(Java、C/C++)

#資料結構與演算法學習筆記#劍指Offer35:是否平衡二叉樹/AVL樹 + 測試用例(Java、C/C++)

2018.11.3

前幾天有用遞迴實現了二叉樹的深度#資料結構與演算法學習筆記#劍指Offer36:二叉樹的深度(Java),因此可以對每個結點先序遍歷進行一次平衡驗證,只要確定每個結點都是平衡的,那就可以說明這是一棵平衡二叉樹。

不過這樣就會對多個結點重複遍歷多次。還有一種方法可以對每個結點只遍歷一次。

將檢查平衡的遍歷方式改為後序遍歷,可以做到對每個結點只進行一次訪問。設定非平衡返回標誌值-1,一旦發現不平衡結點立即返回至根節點,可以對演算法進行剪枝處理。

題目描述

輸入一棵二叉樹,判斷該二叉樹是否是平衡二叉樹。

Java實現:

/**
 * 
 * @author ChopinXBP
 * 輸入一棵二叉樹,判斷該二叉樹是否是平衡二叉樹。
 * 
 */

public class IsBalancedTree_37 {

	public static class TreeNode {
	    int val = 0;
	    TreeNode left = null;
	    TreeNode right = null;

	    public TreeNode(int val) {
	        this.val = val;

	    }

	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		TreeNode root1 = new TreeNode(2);
		TreeNode root2 = new TreeNode(1);
		TreeNode root3 = new TreeNode(0);
		TreeNode root4 = new TreeNode(3);
		TreeNode root5 = new TreeNode(4);
		root1.left = root2;
		root2.left = root3;
		//root3.right = root4;
		root1.right = root5;
		System.out.println(IsBalanced_Solution2(root1));
	}

	
	///////////////對每個結點計算深度的方法,重複遍歷了結點///////////////////////
    public static boolean IsBalanced_Solution(TreeNode root) {  
    	if(root == null) return true;
        if(Math.abs(GetDepth(root.left) - GetDepth(root.right)) > 1) return false;
        
        //return isSearchTree(root);
        return true;
    }
    
    private static int GetDepth(TreeNode root){
    	if(root == null)return 0;
    	return Math.max(GetDepth(root.left), GetDepth(root.right)) + 1;
    }
    /*
    //判斷搜尋樹
    private static boolean isSearchTree(TreeNode root){
    	if(root == null) return true;
    	boolean rootflag = true;
    	if(root.left != null && root.val < root.left.val)rootflag = false;
    	if(root.right != null && root.val > root.right.val)rootflag = false;
    	
    	return rootflag && isSearchTree(root.left) && isSearchTree(root.right);
    }
    */
    
    ///////////////對每個結點只遍歷一次,並且進行剪枝處理///////////////////////
    public static boolean IsBalanced_Solution2(TreeNode root) {  
    	if(getTreeDepth(root) == -1)return false;
        return true;
    }
    
    private static int getTreeDepth(TreeNode root){
    	if(root == null)return 0;
    	int leftdepth = getTreeDepth(root.left);
    	if(leftdepth == -1)return -1;		//剪枝處理,一旦出現不平衡,直接返回-1至初始
    	int rightdepth = getTreeDepth(root.right);
    	if(rightdepth == -1)return -1;
    	
    	if(Math.abs(leftdepth - rightdepth) <= 1){
    		return Math.max(leftdepth, rightdepth) + 1;
    	}else{
    		return  -1;		//-1代表不平衡
    	}
    }
}

C++實現示例:

//後續遍歷二叉樹,遍歷過程中求子樹高度,判斷是否平衡
class Solution {
public:
    bool IsBalanced(TreeNode *root, int & dep){
        if(root == NULL){
            return true;
        }
        int left = 0;
        int right = 0;
        if(IsBalanced(root->left,left) && IsBalanced(root->right, right)){
            int dif = left - right;
            if(dif<-1 || dif >1)
                return false;
            dep = (left > right ? left : right) + 1;
            return true;
        }
        return false;
    }
    bool IsBalanced_Solution(TreeNode* pRoot) {
        int dep = 0;
        return IsBalanced(pRoot, dep);
    }
};

#Coding一小時,Copying一秒鐘。留個言點個讚唄,謝謝你#