【剑指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 ...
随机推荐
- Linux C 程序 指针数组和二级指针(TEN)
指针数组和二级指针 #include<stdio.h> int main(){ ] = {,,,,}; ], i; int **pp = p; //使p指针数组指向每一个a ; i < ...
- NSS_02 日志配置
采用log4net,使用系统推荐的最新版本:log4net-1.2.11-bin-newkey.zip(网址:http://logging.apache.org/log4net/download_lo ...
- ObjectInput read方法的坑
最近搞得一个bug,搞了好久既抓包分析数据,又debug竟然就是搞不懂为什么数据只是读了前面一部分.后来仔细研究了一下API,原来这个方法并不是你指的多少就读入多少指定的长度是最大长度,我嚓,太坑爹了 ...
- js字符串长度计算(一个汉字==两个字符)和字符串截取
js字符串长度计算(一个汉字==两个字符)和字符串截取 String.prototype.realLength = function() { return this.replace(/[^\x00-\ ...
- js分割文件快速上传
<?php header('Content-type:text/html;charset=UTF-8'); ?> <?php if ($_FILES) { if(!file_exis ...
- [Linux]学习笔记(4)-su及passwd的用法介绍
(1)su su命令用于将当前的用户切换到一个指定的用户.语法为: su - user_name 如果用户利用telnet方式远程登录,是不能直接以root账户登录的,也就是说在使用telnet登录服 ...
- 用CSS3写的小案例-图片缩放隐藏内容显示
思路分析 (1).搭建界面 (2).鼠标移到图片的时候,放大显示 (3).鼠标移入到当前的li标签里面找到后面的div让其显示出来 <!DOCTYPE html> <html lan ...
- C语言获取网页源代码的学习所得
研究了一天这个玩意感觉挺有意思的. 刚开始是什么都不懂,现在写出来一段代码感觉略微有点意思了. 下面我分享一下学习过程和自己的理解. 整体过程大概就是如下情况: 先搜了一下别人的写这个东西的代码. 研 ...
- 外部表查询时出现ORA-29913和ORA-29400错误
create table t_ext_tab(id char(1),name char(6)) organization external( type oracle_loader default di ...
- 请给出一个左侧定宽右侧自适应的HTML结构及样式
<!DOCTYPE HTML><html><head><meta http-equiv="Content-Type" content=&q ...