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. js 正则实例

    1.匹配url参数 var re = /([^&=]+)=?([^&]*)/g while (r = re.exec("aaa1a=aabbbbbbb")) { a ...

  2. linux环境下配置github远程仓库

    1.设置git用户和邮箱 git config --global user.name "fujinzhou" git config --global user.email &quo ...

  3. KnockoutJS(1)-数据模型

    前言 说到数据模型(ViewModel),就不得不提到MVVM模式,接触过WPF和Silverlight的人应该对这个模式比较熟悉. 不熟悉也没多大关系,因为KnockoutJS的使用相对简单. MV ...

  4. CentOS平台下为Python添加MongoDB支持PyMongo

    下载PyMongo [root@leezhen ~]# wget https://pypi.python.org/packages/source/p/pymongo/pymongo-2.6.3.tar ...

  5. Spark Streaming揭秘 Day14 State状态管理

    Spark Streaming揭秘 Day14 State状态管理 今天让我们进入下SparkStreaming的一个非常好用的功能,也就State相关的操作.State是SparkStreaming ...

  6. 文件大小的友好输出及其 Python 实现

    在数据库中存储时,使用 Bytes 更精确,可扩展性和灵活性都很高. 输出时,需要做一些适配. 1. 注意事项与测试代码 需要考虑 sizeInBytes 为 None 的场景. 除以 1024.0 ...

  7. Oracle全表扫描

    优化器在形成执行计划时需要做的一个重要选择——如何从数据库查询出需要的数据.对于SQL语句存取的任何表中的任何行,可能存在许多存取路径(存取方法),通过它们可以定位和查询出需要的数据.优化器选择其中自 ...

  8. EXTJS 3.0 资料 控件之 GridPanel属性与方法大全

    1.Ext.grid.GridPanel 主要配置项: store:表格的数据集 columns:表格列模式的配置数组,可自动创建ColumnModel列模式 autoExpandColumn:自动充 ...

  9. 原生JS的对象常用操作总结

       前端时间写了篇怎么判断js对象相等的文章,一直在期待大神给点消息,无奈一直杳无音讯,还是自己写个函数来进行判断,下面总结一些常用的对象操作的方法.    咋们来个先抑后扬的方式,先放出几个基本的 ...

  10. Android中Linux suspend/resume流程

    Android中Linux suspend/resume流程首先我们从linux kernel 的suspend说起,不管你是使用echo mem > /sys/power/state 或者使用 ...