判断二叉树是不是平衡二叉树、完全二叉树、满二叉树||C++实现

目录

1 判断二叉树是不是平衡二叉树

2 判断二叉树是不是完全二叉树

3 判断二叉树是不是满二叉树


在这之前,我们假设二叉树节点的结构如下:

typedef struct binaryTreeNode
{
	int mData;
	binaryTreeNode * mLeft;
	binaryTreeNode * mRight;
};

1 判断二叉树是不是平衡二叉树

首先来科普一下什么是平衡二叉树,学过数据结构的应该都知道,这毕竟不是什么新鲜的问题。

首先大家对二叉查找树(二叉排序树)有所了解。 首先平衡二叉树是一棵二叉查找树,另外,以平衡二叉树中所有节点为根的树的左右子树高度之差的绝对值不超过1。

所以在判断二叉树是不是平衡二叉树之前,我们先应该去判断这颗树满足不满足平衡二叉树的基本条件,即这颗树是不是二叉查找树,对于二叉查找树,我们知道由于它满足左小右大的规则,所以二叉查找树的中序遍历序列是从小到大有序的。我们可以根据这个特点去判断一个二叉树是不是二叉查找树

见下面代码:

int predit = INF;//假设INF为已定义的常量,它小于树中的任何值,用predit记录当前访问节点的前驱的值
bool JustBST(binaryTreeNode* root)
{
	if (root == NULL)//空树也是二叉查找树
		return true;
	bool b1 = JustBST(root->mLeft);//递归的判断左子树是否是二叉排序树
	if (b1 == false || predit > root->mData)//左子树不是二叉排序树或者predit的值大于当前根节点的值,则该树不是二叉排序树
		return false;
	predit = root->mData;//将要访问右子树的时候,predit记录下当前根节点的值
	bool b2 = JustBST(root->mRigjt);//递归去判断右子树是否为二叉排序树
	return b2;
}

判断完了二叉树是不是二叉排序树之后,我们再来判断这棵树满足不满足二叉平衡树的性质。

可以递归的去判断左子树是否是平衡的,右子树是否是平衡的,然后再通过比较高度差,判断自身是否是平衡的。见如下代

bool isBalanced(binaryTreeNode* root)
 {
        if(root==NULL)
            return true;
        //判断左右子树是否平衡,并且判断高度差
        if(isBalanced(root->mLeft)&&isBalanced(root->mRight)&&abs(height(root->mLeft)-height(root->mRight))<=1)
            return true;
        return false;
    }
    //得到深度
    int height(binaryTreeNode*root)
    {
        if(root==NULL) return 0;
        int l =  height(root->mLeft)+1;
        int r = height(root->mRight)+1;
        return l>r?l:r;
    }

2 判断二叉树是不是完全二叉树

首先我们知道,如果一个二叉树的深度为k,且1~k-1层的节点数都达到了最大个数,且第k层的节点都集中在左边,那么这样的二叉树就是一个完全二叉树,如下图所示,是一个完全二叉树:

可以看出一颗完全二叉树只可能最后一层的节点不是满的。因此我们可以采用层次遍历的方法来进行判断,在遍历的时候我们只去判断当前节点为不为空,不管子节点为不为空都入队。

如上图所示,当遍历完10这个元素的时候,对列里面全是为NULL的元素,这个时侯我们遍历到一个空元素,这时候不再入队,只需判断队中元素有没有不为空的元素,如果有,那么这个树就不是完全二叉树。

bool IsComTree(binaryTreeNode* t)
{
	if (t == NULL)
		return true;
	//对列
	queue<binaryTreeNode*> que;
	que.push(t);
	while (t=que.front())
	{
		//无论子节点为不为空,都入队
		que.push(t->mLeft);
		que.push(t->mRight);
		que.pop();
	}
	while (!que.empty())
	{
		if (que.front())
			return false;
		que.pop();
	}
	return true;
}

3 判断二叉树是不是满二叉树

在一棵二叉树中,如果所有的分支节点都有左右孩子,并且叶子节点都集中在最后一层,那么这二样的二叉树称为满二叉树,如下图所示:

由于满二叉树的特性,我们可以得满二叉树的一些特性:

  1. 一个层数为k的满二叉树的节点总数为2的k次方j减1,一定是奇数个。
  2. 第i层节点数为2的i减1次方。

因此在判断一颗二叉树是不是满二叉树的时候,可以用上述的两个性质来判断。

int Count(binaryTreeNode* t)
{
	if (t == NULL)
		return 0;
	return 1 + Count(t->mLeft) + Count(t->mRight);
}

int TreeDeep(binaryTreeNode* t)
{
	if (t == NULL)return 0;
	int left = TreeDeep(t->mLeft) + 1, right = TreeDeep(t->mRight) + 1;
	return left > right ? left : right;
}
bool IsFullTree(binaryTreeNode* t)
{
	if (t == NULL)
		return true;
	//节点数
	int num = Count(t);
	//层数
	int deep = TreeDeep(t);
	if (num == pow(2, deep) - 1)
		return true;
	return false;
}

 

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值