王道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

*/

测试结果为

相关推荐
爱研究的小陈几秒前
Day 3:数学基础回顾——线性代数与概率论在AI中的核心作用
算法
渭雨轻尘_学习计算机ing3 分钟前
二叉树的最大宽度计算
算法·面试
再睡一夏就好9 分钟前
Linux常见工具如yum、vim、gcc、gdb的基本使用,以及编译过程和动静态链接的区别
linux·服务器·c语言·c++·笔记
丶Darling.28 分钟前
26考研 | 王道 | 数据结构 | 第八章 排序
数据结构·考研·排序算法
BB_CC_DD36 分钟前
四. 以Annoy算法建树的方式聚类清洗图像数据集,一次建树,无限次聚类搜索,提升聚类搜索效率。(附完整代码)
深度学习·算法·聚类
我也不曾来过11 小时前
list底层原理
数据结构·c++·list
embedded_w2 小时前
U8G2在PC端模拟(C语言版本)
c语言
梁下轻语的秋缘2 小时前
每日c/c++题 备战蓝桥杯 ([洛谷 P1226] 快速幂求模题解)
c++·算法·蓝桥杯
CODE_RabbitV2 小时前
【深度强化学习 DRL 快速实践】逆向强化学习算法 (IRL)
算法
矛取矛求3 小时前
C++区别于C语言的提升用法(万字总结)
c语言·c++