完全/满二叉树相关算法题|判断是否为完全/满二叉树(C)

判断是否是完全二叉树

二叉树按二叉链表形式存储,试编写一个判别给定二叉树是否是完全二叉树的算法

算法思想

根据完全二叉树的定义,具有n个节点的完全二叉树与满二叉树中编号从1~n的节点一一对应。
采用层次遍历算法,将所有节点加入队列(包括空节点),遇到空节点时,查看其后是否有非空节点。若有,则二叉树不是完全二叉树

// 判断给定二叉树是否为完全二叉树
bool IsComplete(BTNode T)
{
	BTNode* cur;
	QueInit(Q);
	if (!T)
	{
		// 空树为满二叉树
		return true;
	}
	EnQueue(Q, T);
	while (!IsEmpty(Q))
	{
		DeQueue(Q, cur);
		if (cur)
		{
			// 节点非空,将其左右子树入队列
			EnQueue(Q, cur->left);
			EnQueue(Q, cur->right);
		}
		else
		{
			// 节点非空,检查其后是否有非空节点
			while (!IsEmpty(Q))
			{
				DeQueue(Q, cur);
				if (cur)
					// 节点非空,则二叉树为非完全二叉树
					return false;
			}
		}
	}
	return true;
}

完全二叉树的定义:
如果一棵二叉树的所有层都被完全填满,除了最后一层(叶子层),并且最后一层的所有节点都尽可能地靠左,那么它就是完全二叉树。

  1. 初始化
    如果二叉树为NULL,直接返回true,空树也被认为是完全二叉树
    初始化一个队列,用于遍历二叉树,并将根节点T入队
  2. 层次遍历二叉树
    队列不为空时:每次从队列中取出一个节点cur
    如果当前节点cur不为空
    将其左右子树分别入队
    如果当前节点cur为空
    进入检查模式,验证其后是否存在非空节点
    如果在此之后存在非空节点,则该二叉树不是完全二叉树,返回false
  3. 结束条件
    如果遍历到队列末尾,且未发现空节点之后还有非空节点的情况,则该二叉树为完全二叉树,返回true

判断是否是满二叉树

判断一棵树是否是满二叉树

算法思想

满二叉树的定义是:
一棵二叉树中,每个节点要么没有子节点,要么有两个子节点,并且所有叶子节点都在同一层。

  1. 递归法: 检查树是否满足:
    所有节点要么有 0 个子节点,要么有 2 个子节点
    左右子树高度相等
  2. 非递归法(层次遍历):通过层次遍历,检查每个节点是否符合满二叉树的条件
代码

递归法

bool IsFullBinaryTree(BTNode* root)
{
    // 空树是满二叉树
    if (!root)
        return true;

    // 如果有一个孩子为空,另一个孩子不为空,肯定不是满二叉树
    if ((!root->left && root->right) || (root->left && !root->right))
        return false;

    // 递归判断左子树和右子树是否为满二叉树
    return IsFullBinaryTree(root->left) && IsFullBinaryTree(root->right);
}

非递归法

bool IsFullBinaryTree(BTNode* root)
{
    if (!root)
        return true;

    Queue Q;
    QueInit(Q);
    EnQueue(Q, root);

    while (!IsEmpty(Q))
    {
        BTNode* cur;
        DeQueue(Q, cur);

        // 如果某个节点有一个孩子为空,另一个不为空,则不是满二叉树
        if ((!cur->left && cur->right) || (cur->left && !cur->right))
            return false;

        // 如果左右孩子都存在,继续遍历
        if (cur->left)
            EnQueue(Q, cur->left);
        if (cur->right)
            EnQueue(Q, cur->right);
    }

    return true;
}

初始化队列:使用队列进行层次遍历,将根节点入队。
逐个检查节点:
如果当前节点有一个孩子为空,另一个孩子不为空,直接返回 false。
如果当前节点有两个孩子,将它们分别入队。
如果当前节点没有孩子或者开始出现子节点为空的情况,则后续所有节点必须为叶子节点,否则返回 false。
遍历完成后,如果未发现不符合的情况,则为满二叉树。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值