左神算法基础class4—题目6判断一棵二叉树是否是平衡二叉树

1.题目:判断一棵二叉树是否是平衡二叉树

2.分析

(1)平衡二叉树的概念

平衡二叉树指对于任意节点,其左右节点高度差不超过1。满二叉树一定是平衡二叉树,平衡二叉树不一定是满二叉树。
在这里插入图片描述
对于4,5节点左右都为空,高度为0,差为0符合;
对于2节点,左高为0,右高为1,差为1符合;
对于3节点,左高为1,右高为0,差为1符合;
对于1节点,左高为2,右高为2,差为0符合;
所以上述树为平衡二叉树。
在这里插入图片描述
增加节点6后,对于3节点,左高为2,右高为0,不符合。

(2)二叉树题解套路

(可阅读树形dp问题)
-使用递归函数来求解二叉树某些问题,对于本题,所有节点都是平衡的,那么整颗树平衡。

  • 1
    对于当前节点x需要的信息如下(列出可能性):
    ①左平衡否:左不平衡则整颗树不平衡
    ②右平衡否:右不平衡则整颗树不平衡
    在都平衡前提下再判断高度差,需要左右子树的高度信息:
    ③左高
    ④右高
  • 2
    设计递归返回结构:递归中需要平衡信息和高度信息
  • 3
    写代码

3.核心代码

(1)树的建立

//树结构
class Tree
{
public:
	int val;
	Tree* left;
	Tree* right;
	Tree(int num)
	{
		this->val = num;
		right = NULL;
		left = NULL;
	}
};
//main函数中
	Tree *head = new Tree(1);
	head->left = new Tree(2);
	head->left->right = new Tree(4);
	head->right = new Tree(3);
	head->right->left = new Tree(5);
	head->right->left->right= new Tree(6);

(2)设计递归返回结构

需要高度信息和是否平衡的信息(true,false)

//返回信息类
class returnData
{
public:
	int h;		//高度
	bool isB;	//平衡否
	returnData(bool isB,int h)//构造函数
	{
		this->h = h;
		this->isB = isB;
	}
};

(3)递归过程

思路:把整个过程视为一个黑盒,假设可以得到左树信息,再得到右树信息,对两棵子树求高度差并判断,最后向上返回。
对整个过程补充一些细节,①一开始时如果当前节点为空,返回平衡true、高度为0;②得到左树信息后如果子树平衡信息为false则直接返回false,右树也是同理;③最后如果高度差不大于1时,说明当前节点平衡,返回给其父节点的信息是平衡true,高度为当前节点高度最大值再加上当前节点(+1)

returnData* process(Tree* head)
{
	if(head == NULL)//空树平衡,高度为0
		return new returnData(true,0);
	
	returnData* leftData = process(head->left);//假设可以在左树收到信息	
	if(!leftData->isB)//已经不平衡直接返回
		return new returnData(false,0);
	
	returnData* rightData = process(head->right);//假设可以在右树收到信息
	if(!rightData->isB)//已经不平衡直接返回
		return new returnData(false,0);

	//在都平衡时求高度差
	if(abs(leftData->h - rightData->h) > 1)
		return new returnData(false,0);
	
	//返回左右树最高高度加1
	return new returnData(true,max(leftData->h , rightData->h) + 1);
}

(4)判断函数

我们只需要递归过程中平衡的信息

bool isBalance(Tree* head)
{
	return process(head)->isB;
}

4.完整代码

#include<iostream>
using namespace std;

//树结构
class Tree
{
public:
	int val;
	Tree* left;
	Tree* right;
	Tree(int num)
	{
		this->val = num;
		right = NULL;
		left = NULL;
	}
};

//需要返回的信息
class returnData
{
public:
	int h;		//高度
	bool isB;	//平衡否
	returnData(bool isB,int h)//构造函数
	{
		this->h = h;
		this->isB = isB;
	}
};

//递归
returnData* process(Tree* head)
{
	if(head == NULL)//空树平衡,高度为0
		return new returnData(true,0);
	
	returnData* leftData = process(head->left);//假设可以在左树收到信息	
	if(!leftData->isB)//已经不平衡直接返回
		return new returnData(false,0);
	
	returnData* rightData = process(head->right);//假设可以在右树收到信息
	if(!rightData->isB)//已经不平衡直接返回
		return new returnData(false,0);

	//在都平衡时求高度差
	if(abs(leftData->h - rightData->h) > 1)
		return new returnData(false,0);
	
	//返回左右树最高高度加1
	return new returnData(true,max(leftData->h , rightData->h) + 1);
}

//判断函数
bool isBalance(Tree* head)
{
	return process(head)->isB;
}

int main()
{
	Tree *head = new Tree(1);
	head->left = new Tree(2);
	head->left->right = new Tree(4);
	head->right = new Tree(3);
	head->right->left = new Tree(5);
	head->right->left->right= new Tree(6);

	cout<<isBalance(head);
	
	system("pause");
	return 0;
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值