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

*/

测试结果为

相关推荐
WPG大大通6 分钟前
基于DIODES AP43781+PI3USB31531+PI3DPX1207C的USB-C PD& Video 之全功能显示器连接端口方案
c语言·开发语言·计算机外设·开发板·电源·大大通
从以前20 分钟前
【算法题解】Bindian 山丘信号问题(E. Bindian Signaling)
开发语言·python·算法
不白兰24 分钟前
[代码随想录23回溯]回溯的组合问题+分割子串
算法
巫师不要去魔法部乱说1 小时前
PyCharm专项练习3 图的存储:邻接矩阵+邻接链表
链表·pycharm
御风@户外1 小时前
质数生成函数、质数判断备份
算法·acm
闻缺陷则喜何志丹1 小时前
【C++动态规划】1105. 填充书架|2104
c++·算法·动态规划·力扣·高度·最小·书架
Dong雨2 小时前
六大排序算法:插入排序、希尔排序、选择排序、冒泡排序、堆排序、快速排序
数据结构·算法·排序算法
析木不会编程2 小时前
【C语言】动态内存管理:详解malloc和free函数
c语言·开发语言
达帮主2 小时前
7.C语言 宏(Macro) 宏定义,宏函数
linux·c语言·算法
是十一月末2 小时前
机器学习之KNN算法预测数据和数据可视化
人工智能·python·算法·机器学习·信息可视化