判斷一棵樹是否是平衡二叉樹及其時間複雜度的優化
阿新 • • 發佈:2019-01-30
平衡二叉樹:它是一棵空樹或者左右子樹的高度差絕對值不超過1,並且左右兩棵子樹都是平衡二叉樹。
要判斷一棵樹是否是平衡二叉樹,由其定義我們很容易想到通過計算出左右兩棵子樹的高度及其高度差來進行判斷。
首先,判斷當前節點是否是平衡二叉樹,則需要開始遍歷整棵樹,求其左右子樹的高度。遞迴判斷其左右子樹是否為平衡二叉樹,又一次需要遍歷其子樹求其高度。多次求其高度,越接近葉子節點的節點高度被求的次數越多。
這種方法很容易理解,但是它的時間複雜度是O(N*N),這是一種十分低效的演算法。後面我們會貼出程式碼。
既然導致低效的原因是因為多次求了節點的高度,因此,考慮將高度放在引數列表中,在遞迴的過程中返回給上一層。
也就是說,從葉子節點開始判斷這棵樹是否是平衡二叉樹。
時間複雜度是O(N)
程式碼:
#include<iostream>
using namespace std;
struct Node
{
int _data;
Node* _left;
Node* _right;
Node(const int& x)
: _data(x)
, _left(NULL)
, _right(NULL)
{}
};
size_t Depth(Node* root)
{
if (root == NULL)
return 0;
size_t left = Depth(root->_left);
size_t right = Depth(root->_right);
return left > right ? left + 1 : right + 1;
}
//bool IsBalanceN(Node* root)
//{//O(n*n)
// if (root == NULL)
// return true;
// int leftDepth = Depth(root->_left);
// int rightDepth = Depth(root->_right);
// return abs(leftDepth - rightDepth) < 2 && IsBalance(root->_left) && IsBalance(root->_right);
//}
bool IsBalance(Node* root, int depth)
{//O(n)
if (root == NULL)
{
depth = 0;
return true;
}
int leftDepth = 0;
if (IsBalance(root->_left, leftDepth) == false)
return false;
int rightDepth = 0;
if (IsBalance(root->_right, rightDepth) == false)
return false;
depth = leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;
return abs(leftDepth - rightDepth) < 2;
}
int main()
{
Node* p1 = new Node(1);
Node* p2 = new Node(1);
Node* p3 = new Node(1);
Node* p4 = new Node(1);
Node* p5 = new Node(1);
p1->_left = p2;
p1->_right = p3;
p2->_left = p4;
p2->_right = p5;
cout<<IsBalance(p1,0);
return 0;
}