C++算法题——平衡二叉树判断


平衡二叉树

简介

AVL树的名字来源于它的发明作者G.M. Adelson-Velsky 和 E.M. Landis。AVL树是最先发明的自平衡二叉查找树(Self-Balancing Binary Search Tree,简称平衡二叉树)。

平衡二叉树定义(AVL):它或者是一颗空树,或者具有以下性质的二叉排序树:它的左子树和右子树的深度之差(平衡因子)的绝对值不超过1,且它的左子树和右子树都是一颗平衡二叉树。

判断的必要条件

  1. 平衡二叉树一定是二叉搜索树
  2. 平衡二叉树的左右子树的高度差不超过1

题目实例

二叉树的平衡性:
利用二叉树遍历的思想,编写一个判断二叉树是否是一棵平衡二叉树的算法。
输入:第一行输入n,表示有n个数组元素,第二行输入二叉树的拓展前序遍历数组,空结点用0表示
输出:true或false
样例输入1:
11
50 45 46 0 0 0 65 0 70 0 0
样例输出1:false
样例输入2:
11
50 45 45 0 0 0 65 0 70 0 0
样例输出2:true

代码实现

#include<iostream>
using namespace std;
typedef struct node									//二叉树结构定义
{
	int data;
	struct node* left, * right;
}BiNode,*BiTree;

void CreateTree(BiTree& root, int arr[],int n);		//生成二叉树
void PreOrder(BiTree root);							//判断是否为搜索二叉树
int height(BiTree root);							//判断左右子树高度

int flag = 0;							//用于标记左右子树的最大高度差
int flag1 = 0, flag2 = 0;				//用于标记二叉树的左右节点是否符合搜索二叉树的定义
int i = 0;								//用于标记生成二叉树途中数组元素的位置
int main()
{
	int n, arr[1000];			
	cin >> n;
	for (int i = 0; i < n; i++)
		cin >> arr[i];					//获取数组元素
	BiTree root = NULL, p = NULL;
	CreateTree(root, arr, i);			//先序序列数组转为二叉树
	PreOrder(root);						//先序遍历中判断是否符合搜索二叉树
	if (flag1 == 0&&flag2==0)			//二者均为0说明符合搜索二叉树
	{
		height(root);					//判断任意节点左右子树高度差是否小于等于1,小于则是AVL
		if (flag <= 1)
			cout << "true";
		else
			cout << "false";
	}
	else
		cout << "flase";
	return 0;
}
void CreateTree(BiTree& root, int arr[],int n)	//将数组转为二叉树
{
	if (i >= n)									//数组元素转化完毕,所有递归都开始退出
		return;
	if (arr[i] == 0)
	{
		i++;
		return;
	}
	root = new BiNode;
	root->left = root->right = NULL;
	root->data = arr[i++];
	CreateTree(root->left, arr,n);				//录入左子树
	CreateTree(root->right, arr,n);				//录入右子树
}
//用先序遍历来判断是否符合搜索二叉树定义
//即左节点小于父节点,右节点大于父节点
void PreOrder(BiTree root)
{
	if (root == NULL)							//遇见空节点退出
		return ;
	if (root->left != NULL)						//左节点不为空进进去判断与父节点大小关系
	{
		if (root->left->data > root->data)		//如果左节点大于父节点,说明不符合搜索二叉树定义,因此将flag1标记为1
		{										//表明不是AVL树
			flag1 = 1;	
		}
	}
	if (root->right != NULL)					//同理,判断右节点与父节点关系
	{
		if (root->right->data < root->data)		//如果右节点小于父节点,违反搜索二叉树定义,flag2标记为1
		{										//表明不是AVL树
			flag2 = 1;
		}
	}
	PreOrder(root->left);						//递归判断左子树
	PreOrder(root->right);						//递归判断右子树
}
//随便取名了,用来求树高,同时判断节点的左右子树的高度差
int height(BiTree root)
{
	if (root == NULL)							//空结点的高度为0
	{
		return 0;
	}
	int h1 = height(root->left) + 1;			//左子树高度加1即是从左子树往上数的本层高度
	int h2 = height(root->right) + 1;			//右子树高度加1即是右子树往上数的本层高度
	/*
	h1与h2之间差的绝对值即是左右子树的高度差,而flag=max{flag,左右子树高度差}
	*/
	if (h1 > h2)								
	{
		flag = flag > h1 - h2 ? flag : h1 - h2;	
	}
	else
	{
		flag = flag > h2 - h1 ? flag : h2 - h1;
	}
	return h1 > h2 ? h1 : h2;				//左右子树高度+1后更大的才是本层的高度
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值