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. apache重写字段详细说明

    用Apache虚拟主机的朋友很多,apache提供的.htaccess模块可以为每个虚拟主机设定rewrite规则,这对网站SEO优化相当有用,同时也改善了用户体验.国内的虚拟机一般不提供.htacc ...

  2. DWZ 刷新 dialog

    DWZ刷新dialog: 1,在删除按钮上添加callback属性;如:(callback="dialogAjax") <a class="delImg" ...

  3. java.imageIo给图片添加水印

    最近项目在做一个商城项目, 项目上的图片要添加水印①,添加图片水印;②:添加文字水印; 一下提供下个方法,希望大家可以用得着: package com.blogs.image; import java ...

  4. css3选择器二

    在HTML中,通过各种各样的属性可以给元素增加很多附加的信息,了解和掌握css3一些的选择器,是很有必要的. :enabled 和 :disabled选择器表单元素有可用(“:enabled”)和不可 ...

  5. NoSQL专家王涛访谈:为什么我们还要做一个NoSQL?

    ChinaUnix:各位网友大家好,今天有幸请到王涛先生到CU做客,与大家交流一些工作经验.首先请王涛先介绍一下自己. 王涛:大家好,我是王涛.过去八年里我一直在IBM多伦多实验室从事DB2引擎研发的 ...

  6. php学习日志(3)-echo&print

    在php中,结果输出一共有两种方式:echo和print,下面将对两种方式做一个比较. echo与print的区别:   echo print 连续输出字符串 能连续输出多个字符串 只能输出一个字符串 ...

  7. jooml二次开发---添加文章组件

    在写一个joomla组件的时候需要手动添加excel表格,并把表格当做文章的内容添加到前台文章中, 开始不知道怎么下手,索性先把一个基本的组件写出来,在joomla网站上测试是可以访问这个组件的,在p ...

  8. Python: tkinter实例改名小工具

    #!/usr/bin/env python #coding=utf-8 # # 版权所有 2014 yao_yu (http://blog.csdn.net/yao_yu_126) # 本代码以MIT ...

  9. C语言获取网页源代码的学习所得

    研究了一天这个玩意感觉挺有意思的. 刚开始是什么都不懂,现在写出来一段代码感觉略微有点意思了. 下面我分享一下学习过程和自己的理解. 整体过程大概就是如下情况: 先搜了一下别人的写这个东西的代码. 研 ...

  10. Js 处理将时间转换 “年-月-日”

    将时间  \/Date(1432828800000+0800)\/"  转换成:“年-月-日” //时间转换function ChangeDateFormat(val) {    if (v ...