判斷一棵樹是否是平衡二叉樹及其時間複雜度的優化

平衡二叉樹:它是一棵空樹或者左右子樹的高度差絕對值不超過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;
}
發佈了67 篇原創文章 · 獲贊 6 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章