【剑指offer】判断二叉树是否为平衡二叉树
2013-09-03 14:49
549 查看
2013-09-03 14:16:51
面试题39:求二叉树的深度、判断二叉树是否为平衡二叉树
小结:
根据平衡二叉树的定义,需要判断每个结点,因此,需要遍历二叉树的所有结点,并判断以当前结点为根的树是否为二叉树;
用后序遍历的方式,先判断左右子树是否为平衡的,在判断当前节点;
可以对每个结点求深度,根据深度判断,如函数IsBanlancedTreeBasic所示,但这种方法存在重复遍历,效率较低;
后序遍历时,一边判断是否为平衡二叉树,一边求而二叉树的深度,这样就避免了重复遍历,如函数IsBanlancedTree所示。
代码编写注意事项:
注意IsBanlancedTreeSub中需同时带回深度,因此在返回为true时,需要更新*pDepth的值;
写代码时,注意下面的代码由于优先级会造成错误
if ( (lchilDepth - rchilDepth) < -1 || (lchilDepth - rchilDepth) > 1)
因此改为:
代码(测试通过,暂未发现问题,欢迎交流指正):
测试结果:
面试题39:求二叉树的深度、判断二叉树是否为平衡二叉树
小结:
根据平衡二叉树的定义,需要判断每个结点,因此,需要遍历二叉树的所有结点,并判断以当前结点为根的树是否为二叉树;
用后序遍历的方式,先判断左右子树是否为平衡的,在判断当前节点;
可以对每个结点求深度,根据深度判断,如函数IsBanlancedTreeBasic所示,但这种方法存在重复遍历,效率较低;
后序遍历时,一边判断是否为平衡二叉树,一边求而二叉树的深度,这样就避免了重复遍历,如函数IsBanlancedTree所示。
代码编写注意事项:
注意IsBanlancedTreeSub中需同时带回深度,因此在返回为true时,需要更新*pDepth的值;
写代码时,注意下面的代码由于优先级会造成错误
if ( (lchilDepth - rchilDepth) < -1 || (lchilDepth - rchilDepth) > 1)
因此改为:
int diff = lchilDepth - rchilDepth; if ( diff < -1 || diff > 1) { return false; }
代码(测试通过,暂未发现问题,欢迎交流指正):
#include <iostream> #include <cassert> using namespace std; typedef char DataType; const DataType LeafNode = '*'; const size_t SIZE = 1000; typedef struct binaryTreeNode { DataType data; binaryTreeNode *lchild; binaryTreeNode *rchild; }BTNode,*PBTNode; //创建二叉树 PBTNode CreatBiTree(PBTNode &pRoot) { DataType newData = 0; cin>>newData; if (newData == LeafNode) { return NULL; } pRoot = new BTNode; pRoot->data = newData; pRoot->lchild = CreatBiTree(pRoot->lchild); pRoot->rchild = CreatBiTree(pRoot->rchild); return pRoot; } //访问二叉树结点 void VisitBiTreeNode(const PBTNode &pBTNode) { assert(NULL != pBTNode); cout<<pBTNode->data<<"\t"; } //前序遍历二叉树 void PreOrder(const PBTNode &pRoot) { if (pRoot != NULL) { VisitBiTreeNode(pRoot); PreOrder(pRoot->lchild); PreOrder(pRoot->rchild); } } //中序遍历二叉树 void InOrder(const PBTNode &pRoot) { if (pRoot != NULL) { InOrder(pRoot->lchild); VisitBiTreeNode(pRoot); InOrder(pRoot->rchild); } } //后序遍历二叉树 void PostOrder(const PBTNode &pRoot) { if (pRoot != NULL) { PostOrder(pRoot->lchild); PostOrder(pRoot->rchild); VisitBiTreeNode(pRoot); } } //求二叉树深度 size_t GetDepthOfBiTree(const PBTNode &pRoot) { if (NULL == pRoot) { return 0; } size_t lchilDepth = GetDepthOfBiTree(pRoot->lchild); size_t rchilDepth = GetDepthOfBiTree(pRoot->rchild); return ( (lchilDepth > rchilDepth) ? (lchilDepth + 1) : (rchilDepth + 1) ); } //判断是否平衡二叉树,求每个结点的深度,有重复遍历 bool IsBanlancedTreeBasic(const PBTNode &pRoot) { if (pRoot == NULL) //若左子树为空,右子树的深度超过1,判断会出错 return true; //return ( IsBanlancedTree(pRoot->lchild) && IsBanlancedTree(pRoot->rchild) ); if ( !IsBanlancedTreeBasic(pRoot->lchild) || !IsBanlancedTreeBasic(pRoot->rchild) ) { return false; } size_t lchilDepth = GetDepthOfBiTree(pRoot->lchild); size_t rchilDepth = GetDepthOfBiTree(pRoot->rchild); int diff = lchilDepth - rchilDepth; //if ( (lchilDepth - rchilDepth) < -1 || (lchilDepth - rchilDepth) > 1) if ( diff < -1 || diff > 1) { return false; } return true; } //判断是否平衡二叉树,优化,没有重复遍历 bool IsBanlancedTreeSub(const PBTNode &pRoot,size_t *pDepth) { if (pRoot == NULL) { *pDepth = 0; return true; } size_t lchildDepth = 0; size_t rchildDepth = 0; if ( !IsBanlancedTreeSub(pRoot->lchild,&lchildDepth) || !IsBanlancedTreeSub(pRoot->rchild,&rchildDepth) ) { return false; } int diff = lchildDepth - rchildDepth; if ( diff < -1 || diff > 1) { return false; } *pDepth = lchildDepth > rchildDepth ? (lchildDepth + 1) : (rchildDepth + 1); return true; } bool IsBanlancedTree(const PBTNode &pRoot) { size_t Depth = 0; return IsBanlancedTreeSub(pRoot,&Depth); } void DestoryBiTreeNode(PBTNode pRoot) { delete pRoot; } //销毁二叉树 void DestoryBiTree(PBTNode &pRoot) { if (pRoot != NULL) { DestoryBiTree(pRoot->lchild); DestoryBiTree(pRoot->rchild); DestoryBiTreeNode(pRoot); } } //测试二叉树相关操作 void TestBinaryTree() { PBTNode pRoot = NULL; cout<<"Test IsBanlancedTree..."<<endl; //测试IsBanlancedTree while (1) { cout<<"Please enter the binary tree,'*' for leaf node"<<endl; CreatBiTree(pRoot); //Test PreOrder... //cout<<"Test PreOrder..."<<endl; cout<<"The pre order is :"<<endl; PreOrder(pRoot); cout<<endl; //Test InOrder... //cout<<"Test InOrder..."<<endl; cout<<"The in order is :"<<endl; InOrder(pRoot); cout<<endl; //Test PostOrder... //cout<<"Test PostOrder..."<<endl; cout<<"The post order is :"<<endl; PostOrder(pRoot); cout<<endl; cout<<"IsBanlancedTree : "<<IsBanlancedTree(pRoot)<<endl; cout<<"IsBanlancedTreeBasic : "<<IsBanlancedTreeBasic(pRoot)<<endl; cout<<"Test DestoryBiTree..."<<endl; DestoryBiTree(pRoot); } /*cout<<"Test DestoryBiTree..."<<endl; DestoryBiTree(pRoot);*/ } int main() { TestBinaryTree(); return 0; }
测试结果:
Test IsBanlancedTree... Please enter the binary tree,'*' for leaf node ab**c** The pre order is : a b c The in order is : b a c The post order is : b c a IsBanlancedTree : 1 IsBanlancedTreeBasic : 1 Test DestoryBiTree... Please enter the binary tree,'*' for leaf node ab*** The pre order is : a b The in order is : b a The post order is : b a IsBanlancedTree : 1 IsBanlancedTreeBasic : 1 Test DestoryBiTree... Please enter the binary tree,'*' for leaf node a** The pre order is : a The in order is : a The post order is : a IsBanlancedTree : 1 IsBanlancedTreeBasic : 1 Test DestoryBiTree... Please enter the binary tree,'*' for leaf node abc**** The pre order is : a b c The in order is : c b a The post order is : c b a IsBanlancedTree : 0 IsBanlancedTreeBasic : 0 Test DestoryBiTree... Please enter the binary tree,'*' for leaf node abcd****e*f** The pre order is : a b c d e f The in order is : d c b a e f The post order is : d c b f e a IsBanlancedTree : 0 IsBanlancedTreeBasic : 0 Test DestoryBiTree... Please enter the binary tree,'*' for leaf node abd**e**cf*** The pre order is : a b d e c f The in order is : d b e a f c The post order is : d e b f c a IsBanlancedTree : 1 IsBanlancedTreeBasic : 1 Test DestoryBiTree... Please enter the binary tree,'*' for leaf node ** The pre order is : 请按任意键继续. . .
相关文章推荐
- 剑指Offer--039-平衡二叉树(判断一棵二叉树是否是平衡二叉树)[扩展附加题]
- 剑指offer-判断该二叉树是否是平衡二叉树
- 剑指offer 39. 二叉树的深度和判断是否为平衡二叉树
- 剑指offer 输入一棵二叉树,判断该二叉树是否是平衡二叉树。
- 剑指offer 39.判断二叉树是否为平衡二叉树
- 剑指offer 面试题39 求二叉树深度|判断是否为平衡二叉树
- 剑指Offer学习总结-判断二叉树是否是平衡二叉树
- 剑指offer 6.3 知识迁移能力3- 判断二叉树是否是平衡二叉树
- 【面试题】剑指Offer-39-求二叉树的深度和判断一颗树是否为平衡二叉树
- 剑指offer—关于判断二叉树是否为平衡二叉树
- 剑指offer 39-二叉树的深度 判断二叉树是否为平衡二叉树
- 剑指offer:判断是否是平衡二叉树
- 剑指offer面试题之判断一颗二叉树是不是平衡二叉树
- 剑指offer 面试题18 判断二叉树B是否是A的子结构
- 【面试题】剑指offer18--判断一个二叉树是否为另一个二叉树的子结构
- 剑指Offer面试题39二叉树的深度(以及判断平衡二叉树),面试题40数组中只出现一次的数字
- 剑指offer-----判断二叉树是否对称(java版)
- 剑指offer-判断二叉树是否对称
- 剑指Offer 39题 二叉树的深度 && 判断平衡二叉树 Java版
- 剑指offer_二叉树深度 及 是否为平衡二叉树