剑指Offer----面试题39(2):判断是否为平衡二叉树

题目:


输入一颗二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一颗平衡二叉树。

分析:


遍历每个结点的时候,调用函数TreeDepth得到它的左右树的深度。如果每个结点的左右子树的深度相差不超过1,按照定义它就是一颗平衡二叉树。

代码

#include"BinaryTree.h"
#include<iostream>

using namespace std;
using namespace OrdinaryBinaryTreeSpace5;

int TreeDepth(BinaryTreeNode *root)
{
	if (root == nullptr)
		return 0;

	int left = TreeDepth(root->left);
	int right = TreeDepth(root->right);

	return (left > right) ? (left + 1) : (right + 1);
}

bool IsBianryTree = true;

void Judge(BinaryTreeNode *root)
{
	if (root == nullptr)
	{
		IsBianryTree = false;
		return;
	}
	
	//依次判断左子树的深度和右子树的深度
	int left = TreeDepth(root->left);
	int right = TreeDepth(root->right);
	if (left - right < -1 || left - right > 1)
	{
		IsBianryTree = false;
		return;
	}
	return;
}

/*
					1
					/ \
				   2   3
				  / \   \
				 4   5   6
					/
			       7
*/

void test1()
{
	cout << "=====================test1=====================" << endl;
	IsBianryTree = true;
	BinaryTreeNode *node1 = CreateBinaryTreeNode(1);
	BinaryTreeNode *node2 = CreateBinaryTreeNode(2);
	BinaryTreeNode *node3 = CreateBinaryTreeNode(3);
	BinaryTreeNode *node4 = CreateBinaryTreeNode(4);
	BinaryTreeNode *node5 = CreateBinaryTreeNode(5);
	BinaryTreeNode *node6 = CreateBinaryTreeNode(6);
	BinaryTreeNode *node7 = CreateBinaryTreeNode(7);

	ConnectBinaryTreeNodes(node1, node2, node3);
	ConnectBinaryTreeNodes(node2, node4, node5);
	ConnectBinaryTreeNodes(node3, NULL, node6);
	ConnectBinaryTreeNodes(node4, NULL, NULL);
	ConnectBinaryTreeNodes(node5, node7, NULL);
	ConnectBinaryTreeNodes(node6, NULL, NULL);
	ConnectBinaryTreeNodes(node7, NULL, NULL);

	Judge(node1);
	if (IsBianryTree)
		cout << "是平衡二叉树" << endl;
	else
		cout << "NO" << endl;

	DestoryTree(node1);
}

/*
					 1
					/
				   2 
				  / 
				 3
*/

void test2()
{
	cout << "=====================test2=====================" << endl;
	IsBianryTree = true;
	BinaryTreeNode *node1 = CreateBinaryTreeNode(1);
	BinaryTreeNode *node2 = CreateBinaryTreeNode(2);
	BinaryTreeNode *node3 = CreateBinaryTreeNode(3);

	ConnectBinaryTreeNodes(node1, node2, NULL);
	ConnectBinaryTreeNodes(node2, node3, NULL);
	ConnectBinaryTreeNodes(node3, NULL, NULL);

	Judge(node1);
	if (IsBianryTree)
		cout << "是平衡二叉树" << endl;
	else
		cout << "NO" << endl;

	DestoryTree(node1);
}

int main()
{
	test1();
	cout << endl;
	test2();

	system("pause");
	return 0;
}

运行结果:
=====================test1=====================
是平衡二叉树

=====================test2=====================
NO
请按任意键继续. . .

注意:上述代码中的各个结点可能会被重复访问多次,因此这种效率不高。

官方源

bool IsBalanced(BinaryTreeNode *root)
{
	if (root == nullptr)
		return false;

	int left = TreeDepth(root->left);
	int right = TreeDepth(root->right);
	int diff = left - right;
	if (diff > 1 || diff < -1)
		return false;

	return IsBalanced(root->left) && IsBalanced(root->right);
}



方法二


如果我们用后序遍历的方式遍历二叉树的每一个节点,在遍历到一个结点之前我们就已经遍历了它的左右子树。只要在遍历每个结点的时候记住它的深度,我们就可以一边遍历一边判断每个结点是不是平衡的。

代码

#include"BinaryTree.h"
#include<iostream>

using namespace std;
using namespace OrdinaryBinaryTreeSpace5;

bool IsBan(BinaryTreeNode *root, int *depth)
{
	if (root == nullptr)
	{
		*depth = 0;
		return true;
	}

	int left, right;
	if (IsBan(root->left, &left) && IsBan(root->right, &right))
	{
		int diff = left - right;
		if (diff > -1 || diff < 1)
		{
			*depth = (left>right) ? (left + 1) : (right + 1);
			return true;
		}
	}

	return false;
}

void test11()
{
	BinaryTreeNode *node1 = CreateBinaryTreeNode(1);
	BinaryTreeNode *node2 = CreateBinaryTreeNode(2);
	BinaryTreeNode *node3 = CreateBinaryTreeNode(3);
	BinaryTreeNode *node4 = CreateBinaryTreeNode(4);
	BinaryTreeNode *node5 = CreateBinaryTreeNode(5);
	BinaryTreeNode *node6 = CreateBinaryTreeNode(6);
	BinaryTreeNode *node7 = CreateBinaryTreeNode(7);

	ConnectBinaryTreeNodes(node1, node2, node3);
	ConnectBinaryTreeNodes(node2, node4, node5);
	ConnectBinaryTreeNodes(node3, NULL, node6);
	ConnectBinaryTreeNodes(node4, NULL, NULL);
	ConnectBinaryTreeNodes(node5, node7, NULL);
	ConnectBinaryTreeNodes(node7, NULL, NULL);

	int depth = 0;
	bool result = IsBan(node1, &depth);
	if (result)
		cout << "是平衡二叉树,树的深度为" << depth << endl;
	else
		cout << "NO是平衡二叉树,树的深度为" << depth << endl;

	DestoryTree(node1);
}

int main()
{
	test11();
	cout << endl;

	system("pause");
	return 0;
}

运行结果:
是平衡二叉树,树的深度为4

请按任意键继续. . .

注意:我们用后序遍历的方式遍历整棵二叉树。在遍历某节点的左右子节点之后,我们可以根据它的左右子节点的深度判断他是不是平衡的,并得到当前结点的深度。当最后遍历到根节点的时候,也就判断了整棵二叉树是不是平衡二叉树。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值