《剑指offer》第五十五题II:平衡二叉树
// 面试题55(二):平衡二叉树 // 题目:输入一棵二叉树的根结点,判断该树是不是平衡二叉树。如果某二叉树中 // 任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。 #include <cstdio> #include "BinaryTree.h" // ====================方法1==================== int TreeDepth(const BinaryTreeNode* pRoot) { if (pRoot == nullptr) return 0; int left = TreeDepth(pRoot->m_pLeft); int right = TreeDepth(pRoot->m_pRight); return (left > right) ? left + 1 : right + 1; } bool IsBalanced_Solution1(const BinaryTreeNode* pRoot) { if (pRoot == nullptr) return true; int left = TreeDepth(pRoot->m_pLeft); int right = TreeDepth(pRoot->m_pRight); int dif = left - right; if (dif > 1 || dif < -1) return false; return IsBalanced_Solution1(pRoot->m_pLeft) && IsBalanced_Solution1(pRoot->m_pRight); //需要计算所有节点 } // ====================方法2==================== bool IsBalanced(const BinaryTreeNode* pRoot, int* pDepth); bool IsBalanced_Solution2(const BinaryTreeNode* pRoot) { int pDepth = 0; return IsBalanced(pRoot, &pDepth); } bool IsBalanced(const BinaryTreeNode* pRoot, int* pDepth) //计算某个节点的深度并判断其是否二叉树 { if (pRoot == nullptr) { *pDepth = 0; return true; } int left, right; //左右子树深度 if (IsBalanced(pRoot->m_pLeft, &left) && IsBalanced(pRoot->m_pRight, &right)) { int dif = left - right; //深度差 if (dif <= 1 && dif >= -1) { *pDepth = (left > right ? left + 1 : right + 1); return true; } } return false; }
// ====================测试代码==================== void Test(const char* testName, const BinaryTreeNode* pRoot, bool expected) { if (testName != nullptr) printf("%s begins:\n", testName); printf("Solution1 begins: "); if (IsBalanced_Solution1(pRoot) == expected) printf("Passed.\n"); else printf("Failed.\n"); printf("Solution2 begins: "); if (IsBalanced_Solution2(pRoot) == expected) printf("Passed.\n"); else printf("Failed.\n"); } // 完全二叉树 // 1 // / \ // 2 3 // /\ / \ // 4 5 6 7 void Test1() { BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1); BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2); BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3); BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4); BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5); BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6); BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7); ConnectTreeNodes(pNode1, pNode2, pNode3); ConnectTreeNodes(pNode2, pNode4, pNode5); ConnectTreeNodes(pNode3, pNode6, pNode7); Test("Test1", pNode1, true); DestroyTree(pNode1); } // 不是完全二叉树,但是平衡二叉树 // 1 // / \ // 2 3 // /\ \ // 4 5 6 // / // 7 void Test2() { BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1); BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2); BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3); BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4); BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5); BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6); BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7); ConnectTreeNodes(pNode1, pNode2, pNode3); ConnectTreeNodes(pNode2, pNode4, pNode5); ConnectTreeNodes(pNode3, nullptr, pNode6); ConnectTreeNodes(pNode5, pNode7, nullptr); Test("Test2", pNode1, true); DestroyTree(pNode1); } // 不是平衡二叉树 // 1 // / \ // 2 3 // /\ // 4 5 // / // 6 void Test3() { BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1); BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2); BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3); BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4); BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5); BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6); ConnectTreeNodes(pNode1, pNode2, pNode3); ConnectTreeNodes(pNode2, pNode4, pNode5); ConnectTreeNodes(pNode5, pNode6, nullptr); Test("Test3", pNode1, false); DestroyTree(pNode1); } // 1 // / // 2 // / // 3 // / // 4 // / // 5 void Test4() { BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1); BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2); BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3); BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4); BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5); ConnectTreeNodes(pNode1, pNode2, nullptr); ConnectTreeNodes(pNode2, pNode3, nullptr); ConnectTreeNodes(pNode3, pNode4, nullptr); ConnectTreeNodes(pNode4, pNode5, nullptr); Test("Test4", pNode1, false); DestroyTree(pNode1); } // 1 // \ // 2 // \ // 3 // \ // 4 // \ // 5 void Test5() { BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1); BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2); BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3); BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4); BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5); ConnectTreeNodes(pNode1, nullptr, pNode2); ConnectTreeNodes(pNode2, nullptr, pNode3); ConnectTreeNodes(pNode3, nullptr, pNode4); ConnectTreeNodes(pNode4, nullptr, pNode5); Test("Test5", pNode1, false); DestroyTree(pNode1); } // 树中只有1个结点 void Test6() { BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1); Test("Test6", pNode1, true); DestroyTree(pNode1); } // 树中没有结点 void Test7() { Test("Test7", nullptr, true); } int main(int argc, char* argv[]) { Test1(); Test2(); Test3(); Test4(); Test5(); Test6(); Test7(); return 0; }
分析:记录当前节点深度,不用多次遍历子节点。
class Solution { public: bool IsBalanced_Solution(TreeNode* pRoot) { int depth = 0; return IsBalanced(pRoot, &depth); } bool IsBalanced(TreeNode* pRoot, int* depth) { if (pRoot == nullptr) { *depth = 0; return true; } int left, right; if (IsBalanced(pRoot->left, &left) && IsBalanced(pRoot->right, &right)) { int diff = left - right; if (diff <= 1 && diff >= -1) { *depth = ((left > right)? left + 1 : right + 1); return true; } } return false; } };