【剑指offer】判断二叉树是否为平衡二叉树
2013-09-03 14:16:51
面试题39:求二叉树的深度、判断二叉树是否为平衡二叉树
小结:
- 根据平衡二叉树的定义,需要判断每个结点,因此,需要遍历二叉树的所有结点,并判断以当前结点为根的树是否为二叉树;
- 用后序遍历的方式,先判断左右子树是否为平衡的,在判断当前节点;
- 可以对每个结点求深度,根据深度判断,如函数IsBanlancedTreeBasic所示,但这种方法存在重复遍历,效率较低;
- 后序遍历时,一边判断是否为平衡二叉树,一边求而二叉树的深度,这样就避免了重复遍历,如函数IsBanlancedTree所示。
代码编写注意事项:
- 注意IsBanlancedTreeSub中需同时带回深度,因此在返回为true时,需要更新*pDepth的值;
- 写代码时,注意下面的代码由于优先级会造成错误
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】判断二叉树是否为平衡二叉树的更多相关文章
- 剑指Offer:二叉树中和为某一值的路径【34】
剑指Offer:二叉树中和为某一值的路径[34] 题目描述 输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径. ...
- 【剑指Offer】二叉树的下一个结点 解题报告(Python)
[剑指Offer]二叉树的下一个结点 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interviews ...
- 剑指offer 判断树是不是对称的
html, body { font-size: 15px; } body { font-family: Helvetica, "Hiragino Sans GB", 微软雅黑, & ...
- 《剑指offer》 二叉树的镜像
本题来自<剑指offer>二叉树的镜像 题目: 操作给定的二叉树,将其变换为源二叉树的镜像. 二叉树的镜像定义:源二叉树 8 / \ 6 10 / \ / \ 5 7 9 11 镜像二叉树 ...
- 剑指Offer:二叉树打印成多行【23】
剑指Offer:二叉树打印成多行[23] 题目描述 从上到下按层打印二叉树,同一层结点从左至右输出.每一层输出一行. 题目分析 Java题解 package tree; import java.uti ...
- 剑指 Offer 34. 二叉树中和为某一值的路径 + 记录所有路径
剑指 Offer 34. 二叉树中和为某一值的路径 Offer_34 题目详情 题解分析 本题是二叉树相关的题目,但是又和路径记录相关. 在记录路径时,可以使用一个栈来存储一条符合的路径,在回溯时将进 ...
- 剑指 Offer 34. 二叉树中和为某一值的路径
剑指 Offer 34. 二叉树中和为某一值的路径 输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径.从树的根节点开始往下一直到叶节点所经过的节点形成一条路径. 示例: 给定如下 ...
- 力扣 - 剑指 Offer 27. 二叉树的镜像
题目 剑指 Offer 27. 二叉树的镜像 思路1(递归) 我们可以使用深度优先搜索,先递归到链表的末尾,然后从末尾开始两两交换.就相当于后续遍历而已 记得要先保存下来node.right节点,因为 ...
- 【剑指Offer】二叉树的镜像 解题报告(Python)
[剑指Offer]二叉树的镜像 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://www.nowcoder.com/ta/coding-interviews 题 ...
- 【剑指Offer】二叉树中和为某一值的路径 解题报告(Python)
[剑指Offer]二叉树中和为某一值的路径 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-intervi ...
随机推荐
- win8 报file://CBD 0xc0000034 蓝屏
出事的机子是acer aspire v5,开机直接出直蓝屏,报file:/CBD 0xc0000034,英语的意思大约是启动文件错,可以用recovery恢复之类的 现在问题1:有好些有用的文件放在了 ...
- JS 正则 获取URL参数
function getQueryString(name) { var reg = new RegExp("(^|&)" + name + "=([^&] ...
- 【转】Qt使用自带的windeployqt 生成exe来发布软件
集成开发环境 QtCreator 目前生成图形界面程序 exe 大致可以分为两类:Qt Widgets Application 和 Qt Quick Application.下面分别介绍这两类exe ...
- 模仿 ios 分段单选
http://blog.csdn.net/qduningning/article/details/37935227 res/drawable/seg_left.xml <?xml version ...
- 粗谈Android中的对齐
在谈这个之前先啰嗦几个概念. 基线:书写英语单词时为了规范书写会设有四条线,从上至下第三条就是基线.基线对齐主要是为了两个控件中显示的英文单词的基线对齐,如下所示: Start:在看API的时候经常会 ...
- soinn
Growing Cell Structures A Self-Organizing Network for Unsupervised and Supervised Learning Here, and ...
- 增加p()函数,方便开发中对变量打印调试
在开发的过程中,我们经常要输出一下变量看看得到的结果是什么,我们就要根据变量的类型选择使用echo,print_r或者var_dump,brophp框架中的p()函数会自动根据变量类型选择用什么方法为 ...
- Vi 几个实用的命令
vi有三种工作模式:指令模式.编辑模式和命令模式. 我们从打开vi说起,这样可以确定下学习环境,也方便学习者实践.打开vi,当前模式即为指令模式,此时可以按a, i, 或o进入编辑模式,或按:(冒号) ...
- epoll_create, epoll_ctl和epoll_wait
参考代码 #include <iostream> #include <sys/socket.h> #include <sys/epoll.h> #include & ...
- HDU 3487 Splay
给定两种操作,一种是把一个数列的某一段切下来插到剩余数列的某一个位置上. 一种是翻转操作,把数列的某一段进行翻转. 都是Splay的基本操作.标准的Rotateto调整出 [a,b]区间.然后对[a, ...