树-判断完全二叉树

完全二叉树的定义是:除了最后一层外,每一层都是完全填满的,并且最后一层的节点都尽可能地集中在左侧。

实现这个功能的步骤和代码:

第一步:初始化队列和变量

  1. 设定变量:我们需要一个队列来存储二叉树的节点,以及两个指针 frontrear 来指示队列的头部和尾部。
  2. 初始化队列:将根节点入队,并将 frontrear 设置为1,因为队列是空的,根节点是第一个元素。
bool fun(BTNode *p) {
    BTNode *q[maxsize]; // 定义队列
    int front = 0, rear = 0; // 初始化队列的头和尾指针
    if (p == NULL) // 如果树为空,直接返回true
        return true;
    q[++rear] = p; // 根节点入队,rear自增表示队列尾部移动
}

第二步:遍历二叉树

  1. 遍历队列:当队列不为空时,从队列头部取出一个节点。
  2. 处理节点:对于取出的节点,将其左孩子和右孩子分别入队。如果节点为空,继续处理下一个节点。
while (front != rear) { // 当队列不为空时
    p = q[++front]; // 取出队列头部的节点,front自增
    if (p != NULL) { // 如果节点不为空
        q[++rear] = p->lchild; // 左孩子入队
        q[++rear] = p->rchild; // 右孩子入队
    }
}

第三步:检查队列中的节点是否为空

检查队列中的节点是否为空,而不是检查它们是否有孩子。如果一个节点为空,那么它不应该被入队

while (front != rear) {
    p = q[++front];
    if (p != NULL) {
        if (p->lchild != NULL) q[++rear] = p->lchild;
        if (p->rchild != NULL) q[++rear] = p->rchild;
    }
}

第四步:检查是否为完全二叉树

  1. 检查剩余节点:如果队列中还有节点,说明不是完全二叉树,返回false。
  2. 返回结果:如果队列为空,说明是完全二叉树,返回true。
while (front != rear) { // 检查队列是否还有剩余节点
    p = q[++front]; // 取出队列头部的节点
    if (p != NULL) // 如果节点不为空
        return false; // 不是完全二叉树
}
return true; // 是完全二叉树

完整的代码

bool fun(BTNode *p) {
    BTNode *q[maxsize]; // 定义队列
    int front = 0, rear = 0; // 初始化队列的头和尾指针
    if (p == NULL) // 如果树为空,直接返回true
        return true;
    q[rear++] = p; // 根节点入队,rear自增表示队列尾部移动

    while (front != rear) { // 当队列不为空时
        BTNode *node = q[front++]; // 取出队列头部的节点,front自增
        if (node != NULL) { // 如果节点不为空
            if (node->lchild != NULL) q[rear++] = node->lchild; // 左孩子入队
            if (node->rchild != NULL) q[rear++] = node->rchild; // 右孩子入队
        }
    }

    while (front != rear) { // 检查队列是否还有剩余节点
        BTNode *node = q[front++]; // 取出队列头部的节点
        if (node != NULL) // 如果节点不为空
            return false; // 不是完全二叉树
    }
    return true; // 是完全二叉树
}
    1
   / \
  2   3
 / \   \
4   5   6

解释代码中的变量变化:

  1. 初始化队列 q 和队列的头尾指针 frontrear。初始时,front = 0rear = 0

  2. 检查根节点 p 是否为空,如果不为空,则将根节点入队,rear 自增到 1。

  3. 开始循环,直到队列为空(front != rear):

    • 第一次循环,取出队列头部的节点(根节点 1),front 自增到 1。因为节点不为空,所以将左孩子(节点 2)和右孩子(节点 3)入队,rear 自增到 3。

    • 第二次循环,取出队列头部的节点(节点 2),front 自增到 2。因为节点不为空,所以将左孩子(节点 4)和右孩子(节点 5)入队,rear 自增到 5。

    • 第三次循环,取出队列头部的节点(节点 3),front 自增到 3。因为节点不为空,所以将左孩子(节点 6)入队,rear 自增到 6。注意,节点 3 没有右孩子,所以不会入队。

  4. 此时,队列中还有节点(节点 4、5、6),所以继续循环:

    • 第四次循环,取出队列头部的节点(节点 4),front 自增到 4。因为节点为空(在完全二叉树中,如果一个节点没有左孩子,那么它也没有右孩子),所以不进行任何操作。

    • 第五次循环,取出队列头部的节点(节点 5),front 自增到 5。同上,不进行任何操作。

    • 第六次循环,取出队列头部的节点(节点 6),front 自增到 6。同上,不进行任何操作。

  5. 此时,队列为空(front == rear),所以退出循环,并返回 true,表示这是一棵完全二叉树。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值