超详细-数据结构-二叉树概念及结构,堆的概念及结构以及堆的代码的c语言实现

本篇博客将详细讲述二叉树的概念,堆的概念及结构以及堆的代码实现,以及二叉树,堆的相关应用。Top K 问题,堆排序的实现以及二叉树链式结构的实现将在之后的博客更新。你可在目录中找到你想重点阅读的内容。堆的完整代码实现在文章结尾处。

堆的其余文章在主页:

堆排序--TOP-K问题

堆排序的讲解

目录

一、树的概念及结构

1.1 树的概念

1.2 树的相关概念

1.3 树的表示

1.4 树在实际中的运用

二、二叉树概念及结构

2.1 概念

2.2 现实中的二叉树:

2.3 特殊的二叉树:

2.3.1 满二叉树

2.3.2 完全二叉树

2.4 二叉树的存储结构

2.4.1 顺序存储

a. 完全二叉树

a.1 完全二叉树规律:

b. 非完全二叉树

2. 链式存储(此篇省略,只说概念,后续会更新)

三、二叉树的顺序结构

3.1 二叉树的顺序结构

3.2 堆的概念及结构

a.堆的应用:

四、堆的实现

4.1 分析

4.1.1 所要实现的功能:Heap.h

4.1.2  堆的插入(向上调整)

4.1.3 堆的删除(向下调整)(堆的删除是删除根节点)

4.2 代码实现

4.2.1堆的初始化与堆的销毁

4.2.2 堆的插入

4.2.3 堆的删除

4.2.4 取堆顶的数据,堆的个数,堆的判空。

五、完整代码

1.My_Heap.h

2.My_Heap.c

3.测试用例


一、树的概念及结构

1.1 树的概念

       树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。

根结点: 无前驱节点;

树是递归定义的:除根节点外,其余结点被分成M(M>0)个互不相交(子树之间不能有交集)的集合T1、T2、……、Tm,其中每一个集合Ti(1<= i<= m)又是一棵结构与树类似的子树。每棵子树的根结点有且只有一个前驱,可以有0个或多个后继。一颗N个结点的树有N-1条边。

拆解:一个根,n颗子树(n>=0)构成,

根A

子树:B/C/D

1.2 树的相关概念

节点的度:一个节点含有的子树的个数称为该节点的; 如上图:A的为6
叶节点或终端节点:度为0的节点称为叶节点; 如上图:B、C、H、I...等节点为叶节点
非终端节点或分支节点:度不为0的节点; 如上图:D、E、F、G...等节点为分支节点
双亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点; 如上图:A是B的父节点
孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点; 如上图:B是A的孩子节点
兄弟节点:具有相同父节点的节点互称为兄弟节点; 如上图:B、C是兄弟节点
树的度:一棵树中,最大的节点的度称为树的度; 如上图:树的度为6
节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推;
树的高度或深度:树中节点的最大层次; 如上图:树的高度为4
堂兄弟节点:双亲在同一层的节点互为堂兄弟;如上图:H、I互为兄弟节点
节点的祖先:从根到该节点所经分支上的所有节点;如上图:A是所有节点的祖先
子孙:以某节点为根的子树中任一节点都称为该节点的子孙。如上图:所有节点都是A的子孙
森林:由m(m>0)棵互不相交的树的集合称为森林;(并查集就是森林)

1.3 树的表示

        树结构相对线性表就比较复杂了,要存储表示起来就比较麻烦了,既然保存值域,也要保存结点和结点之间的关系,实际中树有很多种表示方式如:双亲表示法,孩子表示法、孩子双亲表示法以及孩子兄弟表示法等。这里就了解最常用的孩子兄弟表示法。

a.孩子兄弟表示法

typedef int DataType;
struct Node
{
struct Node* _firstChild1; // 第一个孩子结点
struct Node* _pNextBrother; // 指向其下一个兄弟结点
DataType _data; // 结点中的数据域
};

如图所示:

1.4 树在实际中的运用

最常用的例如文件目录结构

二、二叉树概念及结构

2.1 概念

一棵二叉树是结点的一个有限集合,该集合:
1. 或者为空
2. 由一个根节点加上两棵别称为左子树和右子树的二叉树组成

从下图可以看出:

1.二叉树不存在度大于2的结点

2.二叉树的子树有左右之分,次序不能颠倒,二叉树是有序树

注意:每个结点最多有两个孩子不等价于度为2的树,度为2的树 就是 二叉树。

2.2 现实中的二叉树:

2.3 特殊的二叉树:

1. 满二叉树:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为K,且结点总数是 ,则它就是满二叉树。

(每一层都是满的)

2. 完全二叉树:完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。 要注意的是满二叉树是一种特殊的完全二叉树。(前h-1层是满的,最后一层不一定满,但是从左到右必须连续)

2.3.1 满二叉树


如图:假设一颗满二叉树的高度为h,第一层结点数:2^0,第二层:2^1,第三层:2^2......可得到第h层的结点数为:2^(h-1)

因此,一个满二叉树的总结点数:  2^0+2^1+2^2+...+2^(h-1) = 2^h - 1

假设有N个结点,可得到的高度为:h = log2(N+1)

2.3.2 完全二叉树

理解了完全二叉树概念之后可知道:

假设高度为h

节点的总数量区间:[2^(h-1)-1,2^h-1]

高度区间:               [(log2N )+ 1,log2(N+1)](当N足够大时,高度几乎就无区别)

2.4 二叉树的存储结构

二叉树一般可以使用两种结构存储,一种顺序结构,一种链式结构。


2.4.1 顺序存储


        顺序结构存储就是使用数组来存储,一般使用数组只适合表示完全二叉树,因为非完全二叉树会有空间的浪费。而现实中使用中只有堆才会使用数组来存储。二叉树顺序存储在物理上是一个数组,在逻辑上是一颗二叉树。

a. 完全二叉树
a.1 完全二叉树规律:

可发现一个规律:父子节点对应下标:

leftchild = parent*2+1,rightchild = parent*2+2

再者,由于数组下标都为整数:(不区分左右孩子)

parent = (child -1)/2   (可自行代入值计算)

b. 非完全二叉树

存入数组中,必须留空,造成空间浪费,才能实现如完全二叉树的规律,不适合数组结构存储,只适合链式存储。

2. 链式存储(此篇省略,只说概念,后续会更新)

二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址 。链式结构又分为二叉链和三叉链,当前阶段还只能讲二叉链,后面会讲到高阶数据结构如红黑树等会用到三叉链。

三、二叉树的顺序结构

3.1 二叉树的顺序结构

        普通的二叉树是不适合用数组来存储的,因为可能会存在大量的空间浪费。而完全二叉树更适合使用顺序结构存储。现实中我们通常把堆(一种二叉树)使用顺序结构的数组来存储,需要注意的是这里的堆和操作系统虚拟进程地址空间中的堆是两回事,一个是数据结构,一个是操作系统中管理内存的一块区域分段。

3.2 堆的概念及结构

注意:每棵树的根,都是这棵树的最大/小值。兄弟之间,左孩子不一定小于右孩子

堆排序的时间复杂度:O(N*log2N)

要求:

大堆:任意一个父亲 >= 孩子

小堆:任意一个父亲 <= 孩子

a.堆的应用:

例如给全国的川菜馆进行一个排名,如果有100万家店,需要排几次? 20次

b.思考几个问题:

1.有序数组一定是堆?  是的

2.堆一定有序吗?      不一定

四、堆的实现

4.1 分析

4.1.1 所要实现的功能:Heap.h

typedef int HPDataType;
typedef struct Heap
{
    HPDataType* _a;
    int _size;
    int _capacity;
}Heap;

//堆的初始化
void HeapInit(Heap* php);
// 堆的销毁
void HeapDestory(Heap* hp);
// 堆的插入
void HeapPush(Heap* hp, HPDataType x);
// 堆的删除
void HeapPop(Heap* hp);
// 取堆顶的数据
HPDataType HeapTop(Heap* hp);
// 堆的数据个数
int HeapSize(Heap* hp);
// 堆的判空
int HeapEmpty(Heap* hp);

我主要针对于堆的插入与删除讲解

4.1.2  堆的插入(向上调整)

思路:将插入值,依次与他的父节点进行比较,若它的值小于(小堆)/大于(大堆),他的父节点的值,那么就进行值的交换。

仔细看图,我们需要往在这已经存在的 小堆 中插入26到数组的最后(设数组大小为size,那么26的下标:size - 1,而在这里 插入26后 size = 11,因此26的下标为 10),我们知道小堆的定义是:父节点 <= 孩子,因此对于26,我们先通过在之前找到的完全二叉树规律,可知26的父节点下标:int((10-1)/2) = 4。即对应值28, 26<28 ,交换26,28的对应下标的值,此时26对应的下标为:4 ,28对应的下标为:10。26应继续与它的父节点进行值比较,新父节点下标:1,对应值:18, 26>18,此时不用再交换,顺序正确。

知道了如何插入,那么如果插入的值比堆的所有值都小,什么情况下退出呢?

如图序号1-7,详细展现了,如果一个比堆内所有值都小的数进入堆后如何变化的图解。

看完此图后,序号7时,14已经到达堆顶,他的下标也变成了0,因此我们循环退出的条件就是下标child  == 0,为什么不使用parent?parent再减就数组越界了。

4.1.3 堆的删除(向下调整)(堆的删除是删除根节点)

思路:将插入值先与堆内最后一个数值进行交换,再删除掉最后一个值。再将插入值与他的孩子节点依次值比较,若插入值大于(小堆)/ 小于(大堆)孩子节点的值时,与孩子节点的值进行交换。为什么不可挪动数据覆盖?(将size+1,从最后一个值开始依次往后挪动),这样会直接破坏整个堆结构,想要实现,时间复杂度太大。

如图:

4.2 代码实现

4.2.1堆的初始化与堆的销毁

//堆的初始化
void HeapInit(Heap* hp)
{
    assert(hp);
    hp->_a = NULL;
    hp->_size = 0;
    hp->_capacity = 0;
}

// 堆的销毁
void HeapDestory(Heap* hp)
{
    assert(hp);
    free(hp->_a);
    hp->_a = NULL;
    hp->_size = hp->_capacity = 0;
}

4.2.2 堆的插入

//交换子节点与父节点的值

void Swap(HPDataType* p1, HPDataType* p2)//传的是地址
{
    HPDataType tmp = *p1;
//这里就是解引用取值
    *p1 = *p2;
    *p2 = tmp;
}

//调整堆结构
void AdjustUp(HPDataType* a, int child)
{
    int parent = (child - 1) / 2;
    while (child > 0)
    {
        if (a[child] < a[parent])
        {
            Swap(&a[child], &a[parent]);
//交换子节点与父节点的值
            child = parent;
            parent = (parent - 1) / 2;
//parent = (child - 1) / 2
        }
        else
        {
            break;
        }
    }
}


// 堆的插入
void HeapPush(Heap* hp, HPDataType x)
{
    assert(hp);
    if (hp->_size == hp->_capacity)
    {
        int newCapacity = hp->_capacity = 0 ? 4 : hp->_capacity * 2;
        HPDataType* obj = (HPDataType*)realloc(hp->_a, sizeof(HPDataType) * 2);
        if (obj == NULL)
        {
            perror("realoc fail");
            exit(-1);
        }
        hp->_a = obj;
        hp->_capacity = newCapacity;
    }

    hp->_a[hp->_size] = x;
    hp->_size++;
    AdjustUp(hp->_a, hp->_size - 1);
//调整堆结构
}

4.2.3 堆的删除

void Adjustdown(HPDataType* a, int size, int parent)
{
    int child = parent * 2 + 1;
    while (child <= size - 1)
    {

        //这里可能发生越界若不写(child + 1) <= size - 1
        if ((child + 1) <= size - 1 && a[child + 1] < a[child])
        {
            ++child;
        }
        if (a[child] < a[parent])
        {
            Swap(&a[child], &a[parent]);
            parent = child;
            child = parent * 2 + 1;
        }
        else
        {
            break;
        }

    }
}
// 堆的删除
void HeapPop(Heap* hp)
{
    assert(hp);
    assert(hp->_size > 0);
    Swap(&hp->_a[0], &hp->_a[hp->_size - 1]);
    hp->_size--;
    Adjustdown(hp->_a, hp->_size , 0);
//记得传入插入数据的值
}

4.2.4 取堆顶的数据,堆的个数,堆的判空。

// 取堆顶的数据
HPDataType HeapTop(Heap* hp)
{
    assert(hp);
    assert(hp->_size > 0);
    return hp->_a[0];
}
// 堆的数据个数
int HeapSize(Heap* hp)
{
    assert(hp);
    return hp->_size;

}
// 堆的判空
int HeapEmpty(Heap* hp)
{
    assert(hp);
    return hp->_size == 0;
}

 

五、完整代码

1.My_Heap.h

#include<stdio.h>
#include<assert.h>
#include<stdbool.h>
#include<stdlib.h>
typedef int HPDataType;
typedef struct Heap
{HPDataType* _a;int _size;int _capacity;
}Heap;//堆的初始化
void HeapInit(Heap* php);
// 堆的销毁
void HeapDestory(Heap* hp);
// 堆的插入
void HeapPush(Heap* hp, HPDataType x);
// 堆的删除
void HeapPop(Heap* hp);
// 取堆顶的数据
HPDataType HeapTop(Heap* hp);
// 堆的数据个数
int HeapSize(Heap* hp);
// 堆的判空
int HeapEmpty(Heap* hp);

2.My_Heap.c

#include"My_Heap.h"
//堆的初始化
void HeapInit(Heap* hp)
{assert(hp);hp->_a = NULL;hp->_size = 0;hp->_capacity = 0;
}
// 堆的销毁
void HeapDestory(Heap* hp)
{assert(hp);free(hp->_a);hp->_a = NULL;hp->_size = hp->_capacity = 0;
}
void Swap(HPDataType* p1, HPDataType* p2)
{HPDataType tmp = *p1;*p1 = *p2;*p2 = tmp;
}
void AdjustUp(HPDataType* a, int child)
{int parent = (child - 1) / 2;while (child > 0){if (a[child] < a[parent]){Swap(&a[child], &a[parent]);child = parent;parent = (parent - 1) / 2;}else{break;}}
}
// 堆的插入
void HeapPush(Heap* hp, HPDataType x)
{assert(hp);if (hp->_size == hp->_capacity){int newCapacity = hp->_capacity = 0 ? 4 : hp->_capacity * 2;HPDataType* obj = (HPDataType*)realloc(hp->_a, sizeof(HPDataType) * 2);if (obj == NULL){perror("realoc fail");exit(-1);}hp->_a = obj;hp->_capacity = newCapacity;}hp->_a[hp->_size] = x;hp->_size++;AdjustUp(hp->_a, hp->_size - 1);
}
void Adjustdown(HPDataType* a, int size, int parent)
{int child = parent * 2 + 1;while (child <= size - 1){if ((child + 1) <= size - 1 && a[child + 1] < a[child]){++child;}if (a[child] < a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}
// 堆的删除
void HeapPop(Heap* hp)
{assert(hp);assert(hp->_size > 0);Swap(&hp->_a[0], &hp->_a[hp->_size - 1]);hp->_size--;Adjustdown(hp->_a, hp->_size , 0);
}
// 取堆顶的数据
HPDataType HeapTop(Heap* hp)
{assert(hp);assert(hp->_size > 0);return hp->_a[0];
}
// 堆的数据个数
int HeapSize(Heap* hp)
{assert(hp);return hp->_size;}
// 堆的判空
int HeapEmpty(Heap* hp)
{assert(hp);return hp->_size == 0;
}

3.测试用例

int main()
{int a[] = {15,18,19,25,28,34,65,49,27,37};Heap hp;HeapInit(&hp);for (int i = 0; i < sizeof(a) / sizeof(int); ++i){HeapPush(&hp, a[i]);}//int k = 3;//while (k--)//{//	printf("%d\n", HeapTop(&hp));//	HeapPop(&hp);//}while (!HeapEmpty(&hp)){printf("%d ", HeapTop(&hp));HeapPop(&hp);}printf("\n");return 0;
}

结语:

       随着这篇关于题目解析的博客接近尾声,我衷心希望我所分享的内容能为你带来一些启发和帮助。解题的过程往往充满挑战,但正是这些挑战让我们不断成长和进步。我在准备这篇文章时,也深刻体会到了学习与分享的乐趣。

       在此,我要特别感谢每一位阅读到这里的你。是你的关注和支持,给予了我持续写作和分享的动力。我深知,无论我在某个领域有多少见解,都离不开大家的鼓励与指正。因此,如果你在阅读过程中有任何疑问、建议或是发现了文章中的不足之处,都欢迎你慷慨赐教。         你的每一条反馈都是我前进路上的宝贵财富。同时,我也非常期待能够得到你的点赞、收藏,这将是对我莫大的支持和鼓励。当然,我更期待的是能够持续为你带来有价值的内容,让我们在知识的道路上共同前行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/49845.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何撤销/回滚远程修改

1. git revert 通过git revert commit_id&#xff0c;撤销指定commit&#xff0c;然后push到远程分支&#xff0c;即可撤销指定commit的修改&#xff0c;并新增一个revert的提交记录。 2. 撤销HEAD的修改并删除提交记录 git reset --hard HEAD^ # 撤销最近一次的修改 git pu…

【秋招笔试题】方程

解析&#xff1a;暴力枚举。建议用Python的eval函数,C手写略麻烦。 #include <iostream> #include <string> #include <vector> #include <sstream>using namespace std;long long stringResult(const string &expr) {vector<string> plusP…

文字改视频技术——Rerender A Video

Rerender A Video 的实现技术结合了深度学习、计算机视觉、图像处理、GPU 加速和云计算等多种先进技术&#xff0c;旨在提供高效、优质的视频渲染和增强功能。以下是详细说明&#xff0c;特别突出风格迁移技术的解释。 一、Rerender A Video 介绍 Rerender A Video 利用深度学…

visual studio性能探测器使用案列

visual studio性能探测器使用案列 在visual studio中&#xff0c;我们可以使用自带的工具对项目进行性能探测&#xff0c;具体如下 1.选择性能探查器 Vs2022/Vs2019中打开方式&#xff1a; Vs2017打开方式&#xff1a; 注意最好将解决方案配置为&#xff1a;Release Debu…

昇思25天学习打卡营第22天|CycleGAN图像风格迁移互换

相关知识 CycleGAN 循环生成网络&#xff0c;实现了在没有配对示例的情况下将图像从源域X转换到目标域Y的方法&#xff0c;应用于域迁移&#xff0c;也就是图像风格迁移。上章介绍了可以完成图像翻译任务的Pix2Pix&#xff0c;但是Pix2Pix的数据必须是成对的。CycleGAN中只需…

如何获得某个Window画面所属包名packageName和用户userId

在安卓上获得某个Window画面所属包名packageName和用户userId的方法 1&#xff0c;用到的工具如下&#xff1a; adb androidSDK里的monitor工具 adb shell dumpsys window animator adb shell dumpsys window命令 jdk 1.8已在安卓14模拟器上测试通过。 以AOSP的launcher中的m…

【.NET 6 实战--孢子记账--从单体到微服务】--开发环境设置

在这一小节&#xff0c;我们将设置开发环境。 一、安装SDK 咱们的项目使用的是 .NET6&#xff0c;开发前我们需要从官网上下载.NET6 SDK&#xff08;点击下载&#xff09;&#xff0c;这里要注意的是我们需要下载.NET6 SDK&#xff0c;而不是 .NET6 Runtiem 。SDK 包含 Runti…

C++静态成员变量和静态成员函数

演示代码如下&#xff1a; #include<iostream> using namespace std;class Person { public://静态成员函数 所有对象共享一个函数&#xff0c;且只能调用静态成员变量 ******static void func(){m_A 300;cout << "静态成员函数调用" << endl;}/…

【MySQL进阶之路 | 高级篇】简述Bin Log日志

1. 日志类型 MySQL有不同类型的日志文件&#xff0c;用来存储不同类型的日志&#xff0c;分为二进制日志、错误日志、通用查询日志和慢查询日志&#xff0c;这也是常用的4种。MySQL 8又新增两种支持的日志:中继日志和数据定义语句日志。使用这些日志文件&#xff0c;可以查看M…

openFeign实现服务间调用

以两个模块&#xff08;batch&#xff0c;business&#xff09;为例子&#xff0c;期望实现batch调用business中的hello接口 在主程序batch中引入pom文件 <!--远程调用openfeign--><dependency><groupId>org.springframework.cloud</groupId><arti…

STK 12.9 feature highlights

STK 12.9 feature highlights The workflow for viewing, adding, deleting, and modifying an object’s active Access Constraints has been completely revamped. Using the “Active Constraints” panel in an object’s Properties Browser, you can view all active A…

Linux网络工具“瑞士军刀“集合

一、背景 平常我们在进行Linux服务器相关运维的时候&#xff0c;总会遇到一些网络相关的问题。我们可以借助这些小巧、功能强悍的工具帮助我们排查问题、解决问题。 下面结合之前的一些使用经验为大家介绍一下一些经典应用场景下&#xff0c;这个网络命令工具如何使用的。例如怎…

游泳馆押金原路退回源码解析

<dl class"list "><dd class"address-wrapper dd-padding"><div class"address-container"><cyberdiv style"color:#f0efed;font-size:14px;float:right;position:absolute;right:10px;top: 2px;">●●●<…

java的插桩

可以参考这个&#xff0c;利用Gradle Transform可以实现精准插桩&#xff1a;https://www.51cto.com/article/713694.html

后端面试题日常练-day09 【Java基础】

题目 希望这些选择题能够帮助您进行后端面试的准备&#xff0c;答案在文末 Java中的静态方法和实例方法有何区别&#xff1f; a) 静态方法可以直接通过类名调用&#xff0c;实例方法需要通过对象实例调用 b) 静态方法可以访问实例变量&#xff0c;实例方法可以访问静态变量 c)…

[Python][文件]详细讲解

目录 1.文件操作1.打开文件2.关闭文件3.写文件4.读文件 2.上下文管理器 1.文件操作 1.打开文件 使用内建函数open()打开一个文件f open(D:/test.txt, r)参数&#xff1a; 第一个参数是一个字符串&#xff0c;表示要打开的文件路径第二个参数是一个字符串&#xff0c;表示打开…

MYSQL 第三次作业

1、第三次作业 01、SELECT * FROM student; SELECT * FROM score; 02、SELECT * FROM student LIMIT 1, 3; 03、SELECT * FROM student WHERE department IN (计算机系, 英语系); 04、SELECT * FROM student WHERE birth_year > 1998; 05、SELECT department, COUNT(*) as c…

react的State生命周期

React的State和生命周期是React框架中非常重要的概念&#xff0c;它们共同协作以实现组件的动态更新和高效渲染。以下是对React的State和生命周期的详细解析&#xff1a; React的State 定义与作用&#xff1a; 状态&#xff08;State&#xff09;是React组件内部的数据源&am…

python_从sqlite导出数据至Excel

cursor.fetchall()的方式 import sqlite3 from openpyxl import Workbook# 数据库文件名 db_file D:\\desktop\\ni.db# XLSX 文件名 xlsx_file D:\\desktop\\output2.xlsx# 连接到数据库 conn sqlite3.connect(db_file) cursor conn.cursor()# 执行查询 cursor.execute(&q…

CSP-J模拟赛day1——解析+答案

题目传送门 yjq的吉祥数 题解 送分题&#xff0c;暴力枚举即可 Code #include<bits/stdc.h> using namespace std;int l,r; int num1,tmp0,q[10000],a[10000]; int k (int x){for (int j1;j<tmp;j){if (xq[j])return 0;}return 1; } int main(){while (num<100…