《劍指offer》:[39-1]判斷是否為平衡二叉樹
題目:輸入一棵二叉樹的結點,判斷該樹是不是平衡二叉樹。如果某二叉樹中任意結點的左右子樹的深度相差不超過1,那麼它就是一棵平衡二叉樹。
上圖中的二叉樹就是一棵平衡二叉樹。分析:有了求二叉樹深度的思路後,我們很快就能找到求解該問題的方法,就是從根結點開始開始判斷其左右子結點的深度之差是否為1。如果從根結點開始到葉子結點的每一個結點的左右子樹的深度相差都不超過1,則說明該二叉樹是平衡二叉樹。但是其時間複雜度接近O(N*N),因為裡面有重複的遍歷和訪問。例如我們在判斷8這個根結點是否是平衡的時候,我們需要判斷其左右的兩棵子樹深度的差,需遍歷3,5,7,6,但是當我們判斷5結點是不是平衡的時候,我們還得遍歷3,7,6這三個節點,所以重複的遍歷使效率十分低下。還記得面試12(書上是面試9)中的斐波拉切數列的求法嗎?典型的遞迴,但是那裡的遞迴效率不高,和此題有相同的問題。
具體實現程式碼如下:
#include <iostream>
using namespace std;
struct BinaryTree
{
int data;
BinaryTree *pLeft;
BinaryTree *pRight;
};
BinaryTree *pRoot1=NULL;
int arr[7]={8,5,15,3,7,16,6};
void InserTree(BinaryTree **root,int data)
{
BinaryTree *temp=new BinaryTree;
temp->data=data;
temp->pLeft=temp->pRight=NULL;
if(NULL==*root)
{
*root=temp;
}
else
{
BinaryTree *current=*root;
BinaryTree *back=NULL;
while(current)
{
back=current;
if(data > current->data)
current=current->pRight;
else
current=current->pLeft;
}
if(NULL==back->pLeft)
back->pLeft=temp;
else
back->pRight=temp;
}
}
void CreateTreeLoop(BinaryTree **root,int *array,int length)
{
for(int i=0;i<length;i++)
InserTree(root,array[i]);
}
void Inorder(BinaryTree *root)
{
if(NULL!=root)
{
Inorder(root->pLeft);
cout<<root->data<<" ";
Inorder(root->pRight);
}
}
int TreeDepth(BinaryTree*root)
{
if(NULL==root)
return 0;
int left=TreeDepth(root->pLeft);
int right=TreeDepth(root->pRight);
return left>right?(left+1):(right+1);
}
bool IsBalance(BinaryTree *root)
{
if(NULL==root)
return true;
int leftIsBla=TreeDepth(root->pLeft);
int rightIsBla=TreeDepth(root->pRight);
int diff=leftIsBla-rightIsBla;
if(diff>1 || diff<-1 )
return false;
return IsBalance(root->pLeft) && IsBalance(root->pRight);
}
int main()
{
CreateTreeLoop(&pRoot1,arr,7);
cout<<"中序遍歷:";
Inorder(pRoot1);
cout<<endl;
bool result=IsBalanced(pRoot1);
if(result)
cout<<"The tree is balance!"<<endl;
else
cout<<"The tree is not a balance tree!"<<endl;
system("pause");
return 0;
}
執行結果:
其是實現關鍵程式碼如下:
bool IsBalanceHelp(BinaryTree *root,int *depth)
{
if(root==NULL)
{
*depth=0;
return true;
}
int left,right;
if(IsBalanceHelp(root->pLeft,&left)&& IsBalanceHelp(root->pRight,&right))
{
int diff=left-right;
if(diff<=1 && diff>=-1)
{
*depth=1+(left>right?left:right); //當遍歷每個結點時,記錄下該結點的深度,下次就不用再遍歷已經遍歷過的結點;
return true;
}
}
return false;
}
bool IsBalanced(BinaryTree *root)
{
int depth=0;
return IsBalanceHelp(root,&depth);
}
次種演算法避免了不必要的重複計算,對於資料量大的二叉樹效率明顯提高。相關文章
- 遞迴判斷是否二叉平衡樹遞迴
- 如何判斷一棵樹是否是二叉平衡樹~
- 判斷二叉樹是否為滿二叉樹二叉樹
- 劍指offer——重建二叉樹二叉樹
- LeetCode題解(Offer26):判斷二叉樹A是否為二叉樹B的子樹(Python)LeetCode二叉樹Python
- 劍指offer(四)重建二叉樹二叉樹
- [Python手撕]判斷平衡二叉樹Python二叉樹
- 劍指 Offer 07. 重建二叉樹二叉樹
- 劍指Offer-40-二叉樹的深度二叉樹
- [劍指offer] 把二叉樹列印成多行二叉樹
- 劍指offer——二叉樹的深度C++二叉樹C++
- 【劍指offer】27. 二叉樹的映象二叉樹
- 劍指offer——二叉樹的映象C++二叉樹C++
- LeetCode題解(Offer28):判斷二叉樹是否左右對稱(Python)LeetCode二叉樹Python
- JZ79 判斷是不是平衡二叉樹二叉樹
- LC49判斷二叉樹是否相等二叉樹
- 劍指offer | 55 - I. 二叉樹的深度二叉樹
- 劍指offer讀書筆記:每天一個程式設計題·iOS開發演算法提升計劃(1)(判斷是否為對稱二叉樹)筆記程式設計iOS演算法二叉樹
- 【劍指offer】5.二叉樹的映象和列印二叉樹
- 力扣 - 劍指 Offer 27. 二叉樹的映象力扣二叉樹
- 劍指 Offer 34. 二叉樹中和為某一值的路徑二叉樹
- 劍指offer--把二叉樹列印成多行(C++)二叉樹C++
- # 劍指 Offer 68 - II. 二叉樹的最近公共祖先二叉樹
- 《劍指offer》之在完全二叉樹中新增子節點二叉樹
- 劍指offer——從上往下列印二叉樹C++二叉樹C++
- 【C++】判斷一顆二叉樹是否對稱C++二叉樹
- [劍指offer] 二叉搜尋樹的後序遍歷序列
- leetcode 102 劍指Offer 32 二叉樹的層次遍歷LeetCode二叉樹
- 劍指 Offer 32 - III. 從上到下列印二叉樹 III二叉樹
- 刷題系列 - Python判斷是否映象對稱二叉樹Python二叉樹
- LeetCode 劍指offer——從上到下列印二叉樹 II、從上到下列印二叉樹 IIILeetCode二叉樹
- 劍指 Offer 34. 二叉樹中和為某一值的路徑(java解題)二叉樹Java
- (python版)《劍指Offer》JZ24:二叉樹中和為某一值的路徑Python二叉樹
- 採用層次遍歷判斷二叉樹為完全二叉樹二叉樹
- 劍指offer(java實現)第4題“重建二叉樹”-牛客網Java二叉樹
- 【劍指offer】【4】根據前序和中序結果,重建二叉樹二叉樹
- 劍指 Offer 33. 二叉搜尋樹的後序遍歷序列
- 劍指 Offer 32 - I. 從上到下列印二叉樹(java解題)二叉樹Java
- 判斷序列是否是二叉搜尋樹的後續遍歷