1. 程式人生 > >判斷二叉平衡樹的三種方法

判斷二叉平衡樹的三種方法

/*
題目描述

實現一個函式,檢查二叉樹是否平衡,平衡的定義如下,對於樹中的任意一個結點,
其兩顆子樹的高度差不超過1。
給定指向樹根結點的指標TreeNode* root,請返回一個bool,代表這棵樹是否平衡。
*/

#include <iostream>
#include <cstdlib>
#include <algorithm>

using namespace std;


struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
		val(x), left(NULL), right(NULL) {
	}
};

class Balance {
public:
	
	/*方法一: T(n)=O(nlogn)*/
	bool isBalance(TreeNode* root) {
		// write code here
		if (!root)
			return true;
		else if (abs(height(root->left) - height(root->right)) > 1)
			return false;
		else
			return isBalance(root->left) && isBalance(root->right);

	}
	//求二叉樹高度
	int height(TreeNode *root)
	{
		if (!root)
			return 0;
		else
		{
			return max(height(root->left), height(root->right)) + 1;
		}//ekse
	}

	/*方法二:改進過的演算法,空間複雜度為O(H) 時間複雜度為O(N)*/
	bool isBalance2(TreeNode *root)
	{
		if (checkHeight(root) == -1)
			return false;
		else
			return true;
	}

	/*檢測二叉樹是否平衡,若不平衡返回-1,若平衡返回當前樹的高度*/
	int checkHeight(TreeNode *root)
	{
		/*返回空樹的高度為0*/
		if (root == NULL)
			return 0;

		/*檢查左子樹是否平衡*/
		int leftHeight = checkHeight(root->left);
		/*若返回-1,說明左子樹為非平衡樹*/
		if (leftHeight == -1)
			return -1;

		int rightHeight = checkHeight(root->right);
		if (rightHeight == -1)
			return -1;

		/*檢查當前節點是否平衡*/
		int heightDiff = abs(leftHeight - rightHeight);
		if (heightDiff > 1)
			return -1;
		else{
			/*返回高度*/
			return max(leftHeight, rightHeight) + 1;
		}
	}


	/*方法三:優化演算法T(n)=O(n) S(n)=O(logn)*/
	bool isBalance3(TreeNode *root, int &height)
	{
		if (root == NULL)
		{
			height = 0;
			return true;
		}

		int leftHeight = 0, rightHeight = 0;
		bool leftRet = isBalance3(root->left, leftHeight);
		bool rightRet = isBalance3(root->right, rightHeight);

		height = max(leftHeight, rightHeight) + 1;
		if (abs(leftHeight - rightHeight) > 1)
			return false;
		return leftRet && rightRet;
	}
};