面试题 39,二叉树的深度,以及判断二叉树是否是平衡二叉树 (比较经典的题目)

比较老的题目,最简单版本的代码如下:
int CalcuDepth(TreeNode *root){ if(NULL == root) return 0; int leftDepth = CalcuDepth(root -> m_pLeft); int rightDepth = CalcuDepth(root -> m_pRight); return (leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1); }
接着还有第二问:判断二叉树是否是平衡树,即所有节点左右子树高度差不超过1。
先来个深搜再每次都调用上面的CalcuDepth函数的方法,肯定不能拿出来的。
说得过去的解法是需要把高度的计算和二叉平衡树的判断放在一起,从而避免重复遍历。
我的思路是,函数返回-1表明这个结点不是平衡二叉树,返回-1的条件要么就是左右孩子有一个返回了-1,要么就是当前结点不平衡。要是这些条件都不满足,还是照样返回较大深度。
看看根结点的返回值是不是-1就行了。这种思路比书上要简洁些。
代码:
#include <stdio.h> struct BinaryTreeNode { int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight; }; int JudegeBalancedCore(BinaryTreeNode *root){ if(NULL == root) return 0; int leftDepth = JudegeBalancedCore(root -> m_pLeft); int rightDepth = JudegeBalancedCore(root -> m_pRight); if(leftDepth == -1 || rightDepth == -1) return -1; if(leftDepth - rightDepth > 1 || rightDepth - leftDepth > 1) return -1; return (leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1); } //函数实现 bool JudegeBalanced(BinaryTreeNode *root){ if(NULL == root) return true; return JudegeBalancedCore(root) == -1 ? false : true; } // ====================树代码==================== BinaryTreeNode* CreateBinaryTreeNode(int value) { BinaryTreeNode* pNode = new BinaryTreeNode(); pNode->m_nValue = value; pNode->m_pLeft = NULL; pNode->m_pRight = NULL; return pNode; } void ConnectTreeNodes(BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight) { if(pParent != NULL) { pParent->m_pLeft = pLeft; pParent->m_pRight = pRight; } } void PrintTreeNode(BinaryTreeNode* pNode) { if(pNode != NULL) { printf("value of this node is: %d\n", pNode->m_nValue); if(pNode->m_pLeft != NULL) printf("value of its left child is: %d.\n", pNode->m_pLeft->m_nValue); else printf("left child is null.\n"); if(pNode->m_pRight != NULL) printf("value of its right child is: %d.\n", pNode->m_pRight->m_nValue); else printf("right child is null.\n"); } else { printf("this node is null.\n"); } printf("\n"); } void PrintTree(BinaryTreeNode* pRoot) { PrintTreeNode(pRoot); if(pRoot != NULL) { if(pRoot->m_pLeft != NULL) PrintTree(pRoot->m_pLeft); if(pRoot->m_pRight != NULL) PrintTree(pRoot->m_pRight); } } void DestroyTree(BinaryTreeNode* pRoot) { if(pRoot != NULL) { BinaryTreeNode* pLeft = pRoot->m_pLeft; BinaryTreeNode* pRight = pRoot->m_pRight; delete pRoot; pRoot = NULL; DestroyTree(pLeft); DestroyTree(pRight); } } // ====================测试代码==================== void Test(char* testName, BinaryTreeNode* pRoot, bool expected) { if(testName != NULL) printf("%s begins:\n", testName); if(JudegeBalanced(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, NULL, pNode6); ConnectTreeNodes(pNode5, pNode7, NULL); 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, NULL); 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, NULL); ConnectTreeNodes(pNode2, pNode3, NULL); ConnectTreeNodes(pNode3, pNode4, NULL); ConnectTreeNodes(pNode4, pNode5, NULL); 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, NULL, pNode2); ConnectTreeNodes(pNode2, NULL, pNode3); ConnectTreeNodes(pNode3, NULL, pNode4); ConnectTreeNodes(pNode4, NULL, pNode5); Test("Test5", pNode1, false); DestroyTree(pNode1); } // 树中只有1个结点 void Test6() { BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1); Test("Test6", pNode1, true); DestroyTree(pNode1); } // 树中没有结点 void Test7() { Test("Test7", NULL, true); } int main() { Test1(); Test2(); Test3(); Test4(); Test5(); Test6(); Test7(); return 0; }
书上的思路是用一个引用的方式来额外存储路径值。相对麻烦一些。
代码:
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; }
------------------------------------------------
Felix原创,转载请注明出处,感谢博客园!
posted on 2014-03-02 07:37 Felix Fang 阅读(229) 评论(0) 收藏 举报
浙公网安备 33010602011771号