程序员面试题精选100题(60)-判断二叉树是不是平衡[数据结构]
題目:輸入一棵二叉樹的根結點,判斷該樹是不是平衡二叉樹。如果某二叉樹中任意結點的左右子樹的深度相差不超過1,那么它就是一棵平衡二叉樹。例如下圖中的二叉樹就是一棵平衡二叉樹:
在本系列博客的第27題,我們曾介紹過如何求二叉樹的深度。有了求二叉樹的深度的經驗之后再解決這個問題,我們很容易就能想到一個思路:在遍歷樹的每個結點的時候,調用函數TreeDepth得到它的左右子樹的深度。如果每個結點的左右子樹的深度相差都不超過1,按照定義它就是一棵平衡的二叉樹。這種思路對應的代碼如下:
bool IsBalanced(BinaryTreeNode* pRoot) {if(pRoot == NULL)return true;int left = TreeDepth(pRoot->m_pLeft);int right = TreeDepth(pRoot->m_pRight);int diff = left - right;if(diff > 1 || diff < -1)return false;return IsBalanced(pRoot->m_pLeft) && IsBalanced(pRoot->m_pRight); }
上面的代碼固然簡潔,但我們也要注意到由于一個節點會被重復遍歷多次,這種思路的時間效率不高。例如在函數IsBalance中輸入上圖中的二叉樹,首先判斷根結點(值為1的結點)的左右子樹是不是平衡結點。此時我們將往函數TreeDepth輸入左子樹根結點(值為2的結點),需要遍歷結點4、5、7。接下來判斷以值為2的結點為根結點的子樹是不是平衡樹的時候,仍然會遍歷結點4、5、7。毫無疑問,重復遍歷同一個結點會影響性能。接下來我們尋找不需要重復遍歷的算法。
如果我們用后序遍歷的方式遍歷二叉樹的每一個結點,在遍歷到一個結點之前我們已經遍歷了它的左右子樹。只要在遍歷每個結點的時候記錄它的深度(某一結點的深度等于它到葉節點的路徑的長度),我們就可以一邊遍歷一邊判斷每個結點是不是平衡的。下面是這種思路的參考代碼:
bool IsBalanced(BinaryTreeNode* pRoot, int* pDepth) {if(pRoot == NULL){*pDepth = 0;return true;}int left, right;if(IsBalanced(pRoot->m_pLeft, &left)&& IsBalanced(pRoot->m_pRight, &right)){int diff = left - right;if(diff <= 1 && diff >= -1){*pDepth = 1 + (left > right ? left : right);return true;}}return false; }
我們只需要給上面的函數傳入二叉樹的根結點以及一個表示結點深度的整形變量就可以了:
bool IsBalanced(BinaryTreeNode* pRoot) {int depth = 0;return IsBalanced(pRoot, &depth); }
在上面的代碼中,我們用后序遍歷的方式遍歷整棵二叉樹。在遍歷某結點的左右子結點之后,我們可以根據它的左右子結點的深度判斷它是不是平衡的,并得到當前結點的深度。當最后遍歷到樹的根結點的時候,也就判斷了整棵二叉樹是不是平衡二叉樹了。
博主何海濤對本博客文章享有著作權。網絡轉載請注明出處http://zhedahht.blog.163.com/。整理出版物請和作者聯系。對解題思路有任何建議,歡迎在評論中告知,或者加我微博http://weibo.com/zhedahht或者http://t.163.com/zhedahht與我討論。謝謝。
總結
以上是生活随笔為你收集整理的程序员面试题精选100题(60)-判断二叉树是不是平衡[数据结构]的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 程序员面试题精选100题(58)-八皇后
- 下一篇: 程序员面试题精选100题(61)-数对之