王道p149 7.二叉树按二叉链表形式存储,写一个判别给定二叉树是否是完全二叉树的算法(c语言代码实现)

采用层次遍历算法,将所有结点加入队列(包括空结点)。

如果没有左孩子,就看有没有右孩子,如果有右孩子,那么不为完全二叉树。

如果有左孩子,且之前不存在缺孩子的结点,左孩子进队,如果有右孩子,右孩子也进队,否则就是缺孩子了。之前存在缺孩子的,那么就不是完全二叉树。

有两种代码的写法

本题代码如下

复制代码
int isok(tree* t)//判断完全二叉树
{
    squene q;
    q.f = q.r = q.tag = 0;
    int flag = false; // 标志是否遇到了空节点
    if (*t == NULL)
        return true; // 空树也是完全二叉树
    enquene(&q, *t);
    treenode* p;
    while (!isempty(&q))
    {
        dequene(&q, &p);
        if (p->lchild)
        {
            if (flag) // 如果之前遇到了空节点,说明不是完全二叉树
                return false;
            enquene(&q, p->lchild);
        }
        else
        {
            flag = true;
        }
        if (p->rchild)
        {
            if (flag) // 如果之前遇到了空节点,说明不是完全二叉树
                return false;
            enquene(&q, p->rchild);
        }
        else
        {
            flag = true;
        }
    }
    return true;
}

完整测试代码

复制代码
#include <stdio.h>
#include <stdlib.h>
#define Max 15
#define true 1
#define false 0
typedef struct treenode
{
    char data;
    struct treenode* lchild, * rchild;
} treenode, * tree;
void buildtree(tree* t)
{
    char ch;
    ch = getchar();
    if (ch == '#')
        *t = NULL;
    else
    {
        *t = (treenode*)malloc(sizeof(treenode));
        (*t)->data = ch;
        buildtree(&(*t)->lchild);
        buildtree(&(*t)->rchild);
    }
}
typedef struct squene
{
    struct treenode* data[Max];
    int f, r, tag;
} squene;
int isempty(squene* q)//判断队空
{
    if (q->f == q->r && q->tag == 0)
        return true;
    return false;
}
int isfull(squene* q)//判断队满
{
    if (q->f == q->r && q->tag == 1)
        return true;
    return false;
}
int enquene(squene* q, treenode* p)//进队操作
{
    if (isfull(q))
        return false;
    q->data[q->r] = p;
    q->r = (q->r + 1) % Max;
    q->tag = 1;
    return true;
}
int dequene(squene* q, treenode** p)//出队操作
{
    if (isempty(q))
        return false;
    *p = q->data[q->f];
    q->f = (q->f + 1) % Max;
    q->tag = 0;
    return true;
}
int isok(tree* t)//判断完全二叉树
{
    squene q;
    q.f = q.r = q.tag = 0;
    int flag = false; // 标志是否遇到了空节点
    if (*t == NULL)
        return true; // 空树也是完全二叉树
    enquene(&q, *t);
    treenode* p;
    while (!isempty(&q))
    {
        dequene(&q, &p);
        if (p->lchild)
        {
            if (flag) // 如果之前遇到了空节点,说明不是完全二叉树
                return false;
            enquene(&q, p->lchild);
        }
        else
        {
            flag = true;
        }
        if (p->rchild)
        {
            if (flag) // 如果之前遇到了空节点,说明不是完全二叉树
                return false;
            enquene(&q, p->rchild);
        }
        else
        {
            flag = true;
        }
    }
    return true;
}
int main()
{
    treenode* t;
    buildtree(&t);
    if (isok(&t))
        printf("yes");
    else
        printf("no");
    return 0;
}

用ABD##E##CF##G##测试

/* A

B C

D E F G

*/

用ABD###CF##G##测试

/* A

B C

D F G

*/

还可以用另外一种写法

复制代码
#include <stdio.h>
#include <stdlib.h>
#define Max 15
typedef struct treenode
{
    char data;
    struct treenode* lchild, * rchild;
} treenode, * tree;
void buildtree(tree* t)
{
    char ch;
    ch = getchar();
    if (ch == '#')
        *t = NULL;
    else
    {
        *t = (treenode*)malloc(sizeof(treenode));
        (*t)->data = ch;
        (*t)->lchild = NULL;
        (*t)->rchild = NULL;
        buildtree(&(*t)->lchild);
        buildtree(&(*t)->rchild);
    }
}

int isok(tree* t)//判断完全二叉树
{
    treenode* q[Max];
    int f = -1, r = -1;
    int tag = 1;//标记是否为完全二叉树
    q[++r] = *t;
    treenode* p;
    int flag = 1;//标记缺孩子
    if (*t == NULL) {
        tag = 1;
    }
    if (!(*t)->lchild && !(*t)->rchild)
        tag = 1;
    while (f < r) {
        p = q[++f];
        if (!p->lchild) //没有左孩子缺孩子
        {
            flag = 0;
            if (p->rchild)
                tag = 0;
        }
        else//有左孩子
        {
            if (flag)//之前不存在缺孩子的结点
            {
                q[++r] = p->lchild;
                if (p->rchild)
                    q[++r] = p->rchild;
                else
                    flag = 0;
            }
            else//之前存在缺孩子的结点
                tag = 0;
        }
    }
    if (tag)
        return 1;
    return 0;
}
int main()
{
    treenode* t;
    buildtree(&t);
    if (isok(&t))
        printf("yes");
    else
        printf("no");
    return 0;
}

用ABD##E##CF##G##

/* A

B C

D E F G

*/

测试结果为

用AB#E##CF###

/* A

B C

E F

*/

测试结果为

相关推荐
汉克老师19 小时前
GESP2025年9月认证C++五级真题与解析(单选题9-15)
c++·算法·贪心算法·排序算法·归并排序·gesp5级·gesp五级
lihao lihao19 小时前
c++红黑树
算法
Sarvartha19 小时前
递推与递归笔记
算法
TracyCoder12320 小时前
LeetCode Hot100(1/100)——1. 两数之和 (Two Sum)
算法·leetcode
进击的小头20 小时前
常用数字滤波器的特性与适用场景
c语言·算法
狐5720 小时前
2026-01-19-LeetCode刷题笔记-1292-元素和小于等于阈值的正方形的最大边长
笔记·算法·leetcode
张祥64228890420 小时前
误差理论与测量平差基础笔记六
笔记·算法·概率论
mjhcsp21 小时前
透彻背包DP:从DFS暴力搜索到动态规划的逐步推导
算法·深度优先·动态规划
学嵌入式的小杨同学21 小时前
【嵌入式 C 语言实战】交互式栈管理系统:从功能实现到用户交互全解析
c语言·开发语言·arm开发·数据结构·c++·算法·链表
多米Domi01121 小时前
0x3f 第40天 setnx的分布式锁和redission,写了一天项目书,光背了会儿八股,回溯(单词搜索)
数据结构·算法·leetcode