// 面试题55(二):平衡二叉树
// 题目:输入一棵二叉树的根结点,判断该树是不是平衡二叉树。如果某二叉树中
// 任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。 #include <iostream>
#include "BinaryTree.h" // ====================方法1====================
//迭代的从上到下,判断每个节点是否是平衡树,会导致一个节点的深度重复计算 int TreeDepth(const BinaryTreeNode* pRoot)//检测节点深度
{
if (pRoot == nullptr)
return ; int nLeft = TreeDepth(pRoot->m_pLeft);
int nRight = TreeDepth(pRoot->m_pRight); return (nLeft > nRight) ? (nLeft + ) : (nRight + );
} bool IsBalanced_Solution1(const BinaryTreeNode* pRoot)//记录
{
if (pRoot == nullptr)
return true; int left = TreeDepth(pRoot->m_pLeft);
int right = TreeDepth(pRoot->m_pRight);
int diff = left - right;
if (diff > || diff < -)
return false; return IsBalanced_Solution1(pRoot->m_pLeft)
&& IsBalanced_Solution1(pRoot->m_pRight);
} // ====================方法2====================
//从下到上检测,如果节点是平衡树,就记录其深度,每个节点被计算一次
bool IsBalanced(const BinaryTreeNode* pRoot, int* pDepth); bool IsBalanced_Solution2(const BinaryTreeNode* pRoot)
{
int depth = ;
return IsBalanced(pRoot, &depth);
} bool IsBalanced(const BinaryTreeNode* pRoot, int* pDepth)
{
if (pRoot == nullptr)
{
*pDepth = ;
return true;
} int left, right;
if (IsBalanced(pRoot->m_pLeft, &left)
&& IsBalanced(pRoot->m_pRight, &right))//if条件是找到子节点开始从下向上判断节点是不是平衡树
{
int diff = left - right;
if (diff <= && diff >= -)//如果是,记录最大深度
{
*pDepth = + (left > right ? left : right);
return true;
}
} return false;
} // ====================测试代码====================
void Test(const char* testName, const BinaryTreeNode* pRoot, bool expected)
{
if (testName != nullptr)
printf("%s begins:\n", testName); printf("Solution1 begins: ");
if (IsBalanced_Solution1(pRoot) == expected)
printf("Passed.\n");
else
printf("Failed.\n"); printf("Solution2 begins: ");
if (IsBalanced_Solution2(pRoot) == expected)
printf("Passed.\n");
else
printf("Failed.\n");
} // 完全二叉树
// 1
// / \
// 2 3
// /\ / \
// 4 5 6 7
void Test1()
{
BinaryTreeNode* pNode1 = CreateBinaryTreeNode();
BinaryTreeNode* pNode2 = CreateBinaryTreeNode();
BinaryTreeNode* pNode3 = CreateBinaryTreeNode();
BinaryTreeNode* pNode4 = CreateBinaryTreeNode();
BinaryTreeNode* pNode5 = CreateBinaryTreeNode();
BinaryTreeNode* pNode6 = CreateBinaryTreeNode();
BinaryTreeNode* pNode7 = CreateBinaryTreeNode(); ConnectTreeNodes(pNode1, pNode2, pNode3);
ConnectTreeNodes(pNode2, pNode4, pNode5);
ConnectTreeNodes(pNode3, pNode6, pNode7); Test("Test1", pNode1, true); DestroyTree(pNode1);
} // 不是完全二叉树,但是平衡二叉树
// 1
// / \
// 2 3
// /\ \
// 4 5 6
// /
//
void Test2()
{
BinaryTreeNode* pNode1 = CreateBinaryTreeNode();
BinaryTreeNode* pNode2 = CreateBinaryTreeNode();
BinaryTreeNode* pNode3 = CreateBinaryTreeNode();
BinaryTreeNode* pNode4 = CreateBinaryTreeNode();
BinaryTreeNode* pNode5 = CreateBinaryTreeNode();
BinaryTreeNode* pNode6 = CreateBinaryTreeNode();
BinaryTreeNode* pNode7 = CreateBinaryTreeNode(); ConnectTreeNodes(pNode1, pNode2, pNode3);
ConnectTreeNodes(pNode2, pNode4, pNode5);
ConnectTreeNodes(pNode3, nullptr, pNode6);
ConnectTreeNodes(pNode5, pNode7, nullptr); Test("Test2", pNode1, true); DestroyTree(pNode1);
} // 不是平衡二叉树
// 1
// / \
// 2 3
// /\
// 4 5
// /
//
void Test3()
{
BinaryTreeNode* pNode1 = CreateBinaryTreeNode();
BinaryTreeNode* pNode2 = CreateBinaryTreeNode();
BinaryTreeNode* pNode3 = CreateBinaryTreeNode();
BinaryTreeNode* pNode4 = CreateBinaryTreeNode();
BinaryTreeNode* pNode5 = CreateBinaryTreeNode();
BinaryTreeNode* pNode6 = CreateBinaryTreeNode(); ConnectTreeNodes(pNode1, pNode2, pNode3);
ConnectTreeNodes(pNode2, pNode4, pNode5);
ConnectTreeNodes(pNode5, pNode6, nullptr); Test("Test3", pNode1, false); DestroyTree(pNode1);
} // 1
// /
// 2
// /
// 3
// /
// 4
// /
//
void Test4()
{
BinaryTreeNode* pNode1 = CreateBinaryTreeNode();
BinaryTreeNode* pNode2 = CreateBinaryTreeNode();
BinaryTreeNode* pNode3 = CreateBinaryTreeNode();
BinaryTreeNode* pNode4 = CreateBinaryTreeNode();
BinaryTreeNode* pNode5 = CreateBinaryTreeNode(); ConnectTreeNodes(pNode1, pNode2, nullptr);
ConnectTreeNodes(pNode2, pNode3, nullptr);
ConnectTreeNodes(pNode3, pNode4, nullptr);
ConnectTreeNodes(pNode4, pNode5, nullptr); Test("Test4", pNode1, false); DestroyTree(pNode1);
} // 1
// \
// 2
// \
// 3
// \
// 4
// \
//
void Test5()
{
BinaryTreeNode* pNode1 = CreateBinaryTreeNode();
BinaryTreeNode* pNode2 = CreateBinaryTreeNode();
BinaryTreeNode* pNode3 = CreateBinaryTreeNode();
BinaryTreeNode* pNode4 = CreateBinaryTreeNode();
BinaryTreeNode* pNode5 = CreateBinaryTreeNode(); ConnectTreeNodes(pNode1, nullptr, pNode2);
ConnectTreeNodes(pNode2, nullptr, pNode3);
ConnectTreeNodes(pNode3, nullptr, pNode4);
ConnectTreeNodes(pNode4, nullptr, pNode5); Test("Test5", pNode1, false); DestroyTree(pNode1);
} // 树中只有1个结点
void Test6()
{
BinaryTreeNode* pNode1 = CreateBinaryTreeNode();
Test("Test6", pNode1, true); DestroyTree(pNode1);
} // 树中没有结点
void Test7()
{
Test("Test7", nullptr, true);
} int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
Test7();
system("pause");
return ;
}

《剑指offer》第五十五题(平衡二叉树)的更多相关文章

  1. 剑指Offer(二十五):复杂链表的复制

    剑指Offer(二十五):复杂链表的复制 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/bai ...

  2. 剑指Offer(三十五):数组中的逆序对

    剑指Offer(三十五):数组中的逆序对 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/bai ...

  3. 《剑指offer》第二十五题(合并两个排序的链表)

    // 面试题25:合并两个排序的链表 // 题目:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按 // 照递增排序的.例如输入图3.11中的链表1和链表2,则合并之后的升序链表如链 ...

  4. 《剑指offer》第十五题(二进制中1的个数)

    // 面试题:二进制中1的个数 // 题目:请实现一个函数,输入一个整数,输出该数二进制表示中1的个数.例如 // 把9表示成二进制是1001,有2位是1.因此如果输入9,该函数输出2. #inclu ...

  5. 《剑指offer》第二十六题(树的子结构)

    // 面试题26:树的子结构 // 题目:输入两棵二叉树A和B,判断B是不是A的子结构. #include <iostream> struct BinaryTreeNode { doubl ...

  6. 《剑指offer》第十九题(正则表达式匹配)

    // 面试题19:正则表达式匹配 // 题目:请实现一个函数用来匹配包含'.'和'*'的正则表达式.模式中的字符'.' // 表示任意一个字符,而'*'表示它前面的字符可以出现任意次(含0次).在本题 ...

  7. 《剑指offer》第二十九题(顺时针打印矩阵)

    // 面试题29:顺时针打印矩阵 // 题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字. #include <iostream> void PrintMatrixInC ...

  8. 《剑指offer》第二十八题(对称的二叉树)

    // 面试题28:对称的二叉树 // 题目:请实现一个函数,用来判断一棵二叉树是不是对称的.如果一棵二叉树和 // 它的镜像一样,那么它是对称的. #include <iostream> ...

  9. 《剑指offer》第二十四题(反转链表)

    // 面试题24:反转链表 // 题目:定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的 // 头结点. #include <iostream> #include &quo ...

  10. 《剑指offer》第二十二题(链表中倒数第k个结点)

    // 面试题22:链表中倒数第k个结点 // 题目:输入一个链表,输出该链表中倒数第k个结点.为了符合大多数人的习惯, // 本题从1开始计数,即链表的尾结点是倒数第1个结点.例如一个链表有6个结点, ...

随机推荐

  1. MySQL备份与恢复-mydumper

    上一片博文中,我们说明了mysqldump的备份与恢复.因为mysqldump是单线程导出,单线程恢复的,因此备份与恢复的时间比较长! 首先来安装mydumper: 下载源码:https://gith ...

  2. Java操作Solr之SolrJ

    添加SolrJ的jar包 solrj是访问Solr服务的java客户端,提供索引和搜索的请求方法,SolrJ通常在嵌入在业务系统中,通过SolrJ的API接口操作Solr服务, <depende ...

  3. 【面试篇】必须掌握的Spring 常用注解

    注解本身没有功能的,就和 xml 一样.注解和 xml 都是一种元数据,元数据即解释数据的数据,这就是所谓配置. 本文主要罗列 Spring|Spring MVC相关注解的简介. Spring部分 1 ...

  4. Hibernate properties文件

    ###################### ### Query Language ### ###################### ## define query language consta ...

  5. mysql "The user specified as a definer ('root'@'%') does not exist" 问题

    在重配mysql的时候碰到, 解决办法: 重新授权 grant all privileges on *.* to root@"%" identified by ".&qu ...

  6. 一图解释PHPstorm代码片段设置---附官方文档(转)

    参考:https://blog.csdn.net/thinkthewill/article/details/81145106 资料 设置片段[官方设置教程] 设置变量对话框[官方设置教程] phpst ...

  7. 20165310 NstSec2019 Week3 Exp1 逆向与Bof基础

    20165310 NstSec2019 Week3 Exp1 逆向与Bof基础 一.实验内容 实验目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用fo ...

  8. bzoj 3237 连通图 - 并查集 - 线段树

    Input Output Sample Input 4 5 1 2 2 3 3 4 4 1 2 4 3 1 5 2 2 3 2 1 2 Sample Output Connected Disconne ...

  9. ODAC(V9.5.15) 学习笔记(四)TMemDataSet (3)

    3.其他 名称 类型 说明 GetBlob TBlob 按照字段名获取当前数据集中某个Blob类型的字段值,并以TBlob对象形式返回 Prepared Boolean 检查Query的SQL是否已准 ...

  10. Linux下调整ext3分区大小【转】

    本文转载自:https://blog.csdn.net/cruise_h/article/details/22403529 本文讨论如何再不丢失数据的情况下调整已有ext3分区的大小,包括: 压缩已有 ...