2013-09-03 14:16:51

面试题39:求二叉树的深度、判断二叉树是否为平衡二叉树

小结:

  1. 根据平衡二叉树的定义,需要判断每个结点,因此,需要遍历二叉树的所有结点,并判断以当前结点为根的树是否为二叉树;
  2. 用后序遍历的方式,先判断左右子树是否为平衡的,在判断当前节点;
  3. 可以对每个结点求深度,根据深度判断,如函数IsBanlancedTreeBasic所示,但这种方法存在重复遍历,效率较低;
  4. 后序遍历时,一边判断是否为平衡二叉树,一边求而二叉树的深度,这样就避免了重复遍历,如函数IsBanlancedTree所示。

代码编写注意事项:

  1. 注意IsBanlancedTreeSub中需同时带回深度,因此在返回为true时,需要更新*pDepth的值;
  2. 写代码时,注意下面的代码由于优先级会造成错误

if ( (lchilDepth - rchilDepth) < -1 || (lchilDepth - rchilDepth) > 1)

因此改为:

 int diff = lchilDepth - rchilDepth;
if ( diff < - || diff > )
{
return false;
}

代码(测试通过,暂未发现问题,欢迎交流指正):

 #include <iostream>
#include <cassert>
using namespace std; typedef char DataType;
const DataType LeafNode = '*';
const size_t SIZE = ; typedef struct binaryTreeNode
{
DataType data;
binaryTreeNode *lchild;
binaryTreeNode *rchild;
}BTNode,*PBTNode; //创建二叉树
PBTNode CreatBiTree(PBTNode &pRoot)
{
DataType newData = ; 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 ;
} size_t lchilDepth = GetDepthOfBiTree(pRoot->lchild);
size_t rchilDepth = GetDepthOfBiTree(pRoot->rchild); return ( (lchilDepth > rchilDepth) ? (lchilDepth + ) : (rchilDepth + ) );
} //判断是否平衡二叉树,求每个结点的深度,有重复遍历
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 < - || diff > )
{
return false;
} return true;
} //判断是否平衡二叉树,优化,没有重复遍历
bool IsBanlancedTreeSub(const PBTNode &pRoot,size_t *pDepth)
{
if (pRoot == NULL)
{
*pDepth = ;
return true;
} size_t lchildDepth = ;
size_t rchildDepth = ; if ( !IsBanlancedTreeSub(pRoot->lchild,&lchildDepth) || !IsBanlancedTreeSub(pRoot->rchild,&rchildDepth) )
{
return false;
} int diff = lchildDepth - rchildDepth; if ( diff < - || diff > )
{
return false;
} *pDepth = lchildDepth > rchildDepth ? (lchildDepth + ) : (rchildDepth + );
return true;
} bool IsBanlancedTree(const PBTNode &pRoot)
{
size_t Depth = ;
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 ()
{
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 ;
}

测试结果:

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 :
IsBanlancedTreeBasic :
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 :
IsBanlancedTreeBasic :
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 :
IsBanlancedTreeBasic :
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 :
IsBanlancedTreeBasic :
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 :
IsBanlancedTreeBasic :
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 :
IsBanlancedTreeBasic :
Test DestoryBiTree...
Please enter the binary tree,'*' for leaf node
**
The pre order is :
请按任意键继续. . .

【剑指offer】判断二叉树是否为平衡二叉树的更多相关文章

  1. 剑指Offer:二叉树中和为某一值的路径【34】

    剑指Offer:二叉树中和为某一值的路径[34] 题目描述 输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径. ...

  2. 【剑指Offer】二叉树的下一个结点 解题报告(Python)

    [剑指Offer]二叉树的下一个结点 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interviews ...

  3. 剑指offer 判断树是不是对称的

    html, body { font-size: 15px; } body { font-family: Helvetica, "Hiragino Sans GB", 微软雅黑, & ...

  4. 《剑指offer》 二叉树的镜像

    本题来自<剑指offer>二叉树的镜像 题目: 操作给定的二叉树,将其变换为源二叉树的镜像. 二叉树的镜像定义:源二叉树 8 / \ 6 10 / \ / \ 5 7 9 11 镜像二叉树 ...

  5. 剑指Offer:二叉树打印成多行【23】

    剑指Offer:二叉树打印成多行[23] 题目描述 从上到下按层打印二叉树,同一层结点从左至右输出.每一层输出一行. 题目分析 Java题解 package tree; import java.uti ...

  6. 剑指 Offer 34. 二叉树中和为某一值的路径 + 记录所有路径

    剑指 Offer 34. 二叉树中和为某一值的路径 Offer_34 题目详情 题解分析 本题是二叉树相关的题目,但是又和路径记录相关. 在记录路径时,可以使用一个栈来存储一条符合的路径,在回溯时将进 ...

  7. 剑指 Offer 34. 二叉树中和为某一值的路径

    剑指 Offer 34. 二叉树中和为某一值的路径 输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径.从树的根节点开始往下一直到叶节点所经过的节点形成一条路径. 示例: 给定如下 ...

  8. 力扣 - 剑指 Offer 27. 二叉树的镜像

    题目 剑指 Offer 27. 二叉树的镜像 思路1(递归) 我们可以使用深度优先搜索,先递归到链表的末尾,然后从末尾开始两两交换.就相当于后续遍历而已 记得要先保存下来node.right节点,因为 ...

  9. 【剑指Offer】二叉树的镜像 解题报告(Python)

    [剑指Offer]二叉树的镜像 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://www.nowcoder.com/ta/coding-interviews 题 ...

  10. 【剑指Offer】二叉树中和为某一值的路径 解题报告(Python)

    [剑指Offer]二叉树中和为某一值的路径 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-intervi ...

随机推荐

  1. L009-oldboy-mysql-dba-lesson09

    L009-oldboy-mysql-dba-lesson09 mysql> grant replication salve,replication client on *.* to ‘repl_ ...

  2. 【转】给Winform的button等控件添加快捷键

    ref: http://blog.sina.com.cn/s/blog_4cb9953f0100cy4z.html 第一种:Alt + *(按钮快捷键) 在大家给button.label.menuSt ...

  3. phpcms v9二级栏目生成到根目录后三级栏目无法访问的解决办法

    这个栏目问题折腾了我一天多,可怜我这个美工又不会程序!!! 我的问题是: 我的栏目设置如下: 一级栏目[生成到根目录(是)]> 二级栏目[生成到根目录(是)] > 三级栏目[生成到根目录( ...

  4. win系统一键安装JDK和Tuxedo

    @echo off title JDK和tuxedo环境变量设置 color 0a set /p inputTUX= [请输入你要设置的tuxedo的安装目录:] if /i "%input ...

  5. @properties指针说明

    在iOS开发过程中,属性的定义往往与retain, assign, copy有关,我想大家都很熟悉了,在此我也不介绍,网上有很多相关文章. 现在我们看看iOS5中新的关键字strong, weak, ...

  6. 前端跨域之html5 XMLHttpRequest Level2

    前端代码 var xhr=new XMLHttpRequest(); xhr.open('POST','http://127.0.0.1:8081/ceshi',true); xhr.onreadys ...

  7. ios实现截屏(转)

    -(UIImage*) makeImage {  UIGraphicsBeginImageContext(self.view.bounds.size);  [self.view.layer rende ...

  8. 扩展ExtJs 4.2.1 htmleditor 添加图片功能

    做项目的时候遇到这样一个问题,因为我是用ExtJs做的后台管理框架,所以当我使用ExtJs htmleditor 控件 的时候,发现没有图片上传的功能,于是我打算在网上找找有关的文章,居然真有人写过, ...

  9. 通过android.provider包查看android系统定义的provider.

    原先的2.2的android源码已经不是那么容易找到了,我稍稍搜索了下找到了一两个没速度的死链就失去了兴趣.不过还好忽然发现在android.provider包下包含了常见的provider的使用方法 ...

  10. 我又回来了,这回是带着C++来的

    一晃就是5年,之前在博客园开这个博客主要是跟着大牛学习C#,那个时候自己偏重于asp.net,后来开发了一段时间的Winform.近几年由于工作原因,偏重于测试仪器开发,属于工控行业,主要使用的是C+ ...