程序员面试题精选-- 判断二叉树是不是平衡的
2011-10-05 15:45
246 查看
转自何海涛日志http://zhedahht.blog.163.com/
题目:输入一棵二叉树的根结点,判断该树是不是平衡二叉树。如果某二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。例如下图中的二叉树就是一棵平衡二叉树:
我们很容易就能想到一个思路:在遍历树的每个结点的时候,调用函数TreeDepth得到它的左右子树的深度。如果每个结点的左右子树的深度相差都不超过1,按照定义它就是一棵平衡的二叉树。
参考代码如下:
上面的代码固然简洁,但我们也要注意到由于一个节点会被重复遍历多次,这种思路的时间效率不高。例如在函数IsBalance中输入上图中的二叉树,首先判断根结点(值为1的结点)的左右子树是不是平衡结点。此时我们将往函数TreeDepth输入左子树根结点(值为2的结点),需要遍历结点4、5、7。接下来判断以值为2的结点为根结点的子树是不是平衡树的时候,仍然会遍历结点4、5、7。毫无疑问,重复遍历同一个结点会影响性能。接下来我们寻找不需要重复遍历的算法。
如果我们用后序遍历的方式遍历二叉树的每一个结点,在遍历到一个结点之前我们已经遍历了它的左右子树。只要在遍历每个结点的时候记录它的深度(某一结点的深度等于它到叶节点的路径的长度),我们就可以一边遍历一边判断每个结点是不是平衡的。下面是这种思路的参考代码:
在上面的代码中,我们用后序遍历的方式遍历整棵二叉树。在遍历某结点的左右子结点之后,我们可以根据它的左右子结点的深度判断它是不是平衡的,并得到当前结点的深度。当最后遍历到树的根结点的时候,也就判断了整棵二叉树是不是平衡二叉树了。
题目:输入一棵二叉树的根结点,判断该树是不是平衡二叉树。如果某二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。例如下图中的二叉树就是一棵平衡二叉树:
我们很容易就能想到一个思路:在遍历树的每个结点的时候,调用函数TreeDepth得到它的左右子树的深度。如果每个结点的左右子树的深度相差都不超过1,按照定义它就是一棵平衡的二叉树。
参考代码如下:
//判断二叉树是否为平衡二叉树,该算法特点为简单明了,但会出现结点被重复遍历,效率稍低 bool IsBalanced(BinaryTreeNode *root) { if(root==NULL) return true; else { int left = TreeDepth(root->lchild); int right = TreeDepth(root->rchild); int dif = left - right; if(dif>1 || dif<-1) return false; return IsBalanced(root->lchild) && IsBalanced(root->rchild); } } int TreeDepth(BinaryTreeNode *root) { if(root==NULL) return 0; else { int left_depth = TreeDepth(root->lchild); int right_depth = TreeDepth(root->rchild); return 1 + (left_depth > right_depth ? left_depth : right_depth); } }
上面的代码固然简洁,但我们也要注意到由于一个节点会被重复遍历多次,这种思路的时间效率不高。例如在函数IsBalance中输入上图中的二叉树,首先判断根结点(值为1的结点)的左右子树是不是平衡结点。此时我们将往函数TreeDepth输入左子树根结点(值为2的结点),需要遍历结点4、5、7。接下来判断以值为2的结点为根结点的子树是不是平衡树的时候,仍然会遍历结点4、5、7。毫无疑问,重复遍历同一个结点会影响性能。接下来我们寻找不需要重复遍历的算法。
如果我们用后序遍历的方式遍历二叉树的每一个结点,在遍历到一个结点之前我们已经遍历了它的左右子树。只要在遍历每个结点的时候记录它的深度(某一结点的深度等于它到叶节点的路径的长度),我们就可以一边遍历一边判断每个结点是不是平衡的。下面是这种思路的参考代码:
//更为高效的算法,后序遍历二叉树,遍历每个结点时记录它的深度 bool IsBalanced(BinaryTreeNode *root, int &depth) { if(root==NULL) { depth = 0; return true; } int left,right; if(IsBalanced(root->lchild, left) && IsBalanced(root->rchild, right)) { int dif = left - right; if(dif<=1 && dif>=-1) { depth = 1 + (left > right ? left : right); return true; } } return false; }
在上面的代码中,我们用后序遍历的方式遍历整棵二叉树。在遍历某结点的左右子结点之后,我们可以根据它的左右子结点的深度判断它是不是平衡的,并得到当前结点的深度。当最后遍历到树的根结点的时候,也就判断了整棵二叉树是不是平衡二叉树了。
相关文章推荐
- 程序员面试题精选100题(60)-判断二叉树是不是平衡的
- 程序员面试题精选100题(60)-判断二叉树是不是平衡的
- 程序员面试题精选100题(60)-判断二叉树是不是平衡[数据结构]
- 程序员面试题精选100题(60)-判断二叉树是不是平衡
- 程序员面试题精选100题(60)-判断二叉树是不是平衡的
- 程序员面试题精选100题(60)-判断二叉树是不是平衡
- 程序员面试题精选100题(06)-判断整数序列是不是二元查找树的后序遍历结果
- 程序员面试题精选100题(60)-判断二叉树是不是平衡[数据结构]
- 面试题39:二叉树的深度、判断二叉树是不是平衡
- 程序员面试题精选--06 判断整数序列是不是二元查找树的后序遍历结果
- 程序员面试题精选100题(06)-判断整数序列是不是二元查找树的后序遍历结果
- 【IT笔试面试题整理】判断一个二叉树是否是平衡的?
- 判断二叉树是不是平衡
- [程序员面试题精选100题]4.二叉树中和为某一值的所有路径
- 判断二叉树是不是平衡[数据结构]
- 判断二叉树是不是平衡
- 判断二叉树是不是平衡的
- 判断二叉树是不是平衡
- 面试训练判断二叉树是不是平衡
- 程序员面试题精选100题(48)-二叉树两个结点的最低共同父结点