首页 > 其他分享 >c语言实现最小堆和最大堆

c语言实现最小堆和最大堆

时间:2024-09-25 19:20:16浏览次数:10  
标签:arr 语言 实现 结点 右子 最小 int 数组 节点

第一部分:最大堆和最小堆的基本性质

(1)基本定义

①最大堆

根是这颗树最大的值,每个根节点都比    左右子节点的值大, 对左右子树仍然成立;

②最小堆

根是这颗树的最小的值, 每个根节点都比左右子节点的值小, 同样对左右子树成立;

(2)性质(数组下标关系)

由堆构建的树的背后原理是基于完全二叉树,以及数组下标(从1开始)和完全二叉树节点位置的技巧(即假如说根节点是i,那么它的左儿子=2*i, 右儿子=2*i+1)。

(如数组的下标从0开始),那么(即假如说根节点是i,那么它的左儿子=2*i+1, 右儿子=2*i+2)

第二部分:代码实现前的分析

基本取值范围设置:

①非叶子结点的索引下标取值范围(以数组下标从0开始为例)

除了最底层外,其他层的节点都是满的,而最底层从左到右填充。因此,对于一个有n个元素的堆,最后一个元素的索引是n-1,其父节点的索引是(n-1-1)/2 = (n-2)/2

②对于非叶子结点,肯定有左节点,完全二叉树可能有右结点,也可能没有有右结点。

只有最后一个非叶子结点可能出现上述情况,其他的非叶子结点都是左右节点都有。

③最后一个非叶子结点是否有右结点的判断方式

当我们想要检查一个节点是否有右子节点时,我们需要确保右子节点的索引不会超出数组的范围。因此,我们使用 2 * i + 2 < n 这个条件来判断。如果这个条件成立,说明右子节点的索引小于数组的长度 n,即存在右子节点;否则,说明右子节点的索引超出了数组范围,不存在右子节点。

第三部分:代码实现

#include <stdio.h>
#include <stdio.h>

int jisuan1(int arr[],int n)//如果是最大堆,返回1,否则返回0
{
    for(int i=0;i<=(n-2)/2;i++)
    {
        //左节点判断
        if(arr[i]<arr[2*i+1])
        {
            return 0;
        }
        if((2*i+2<n)&&(arr[i]<arr[2*i+2]))
        {
            return 0;        }
    }
    return 1;
}

int jisuan2(int arr[],int n)//如果是最小堆,返回1,否则返回0
{
    for(int i=0;i<=(n-2)/2;i++)
    {
        //左节点判断
        if(arr[i]>arr[2*i+1])
        {
            return 0;
        }
        if((2*i+2<n)&&(arr[i]>arr[2*i+2]))
        {
            return 0;        }
    }
    return 1;
}

int main() {
    int arr[] = {3,1,4,1,5,9,2,6,5};
    int n = sizeof(arr) / sizeof(arr[0]);
    int result=jisuan1(arr,n);
    if(result==1)
    {
        printf("这是一个最大堆。");
    }
    else
    {
        int result2=jisuan2(arr,n);
        if(result2==1)
        {
            printf("这是一个最小堆。");
        }
        else
        {
            printf("这不是一个有效的堆。");
        }
    }
    return 0;
}

第四部分:效果分析展示

(1)最大堆

输入数组元素为: int arr[] = {5,2,1};

(2)最小堆

输入: int arr[] = {1,2,6,5,7,13};

(3)不是最大最小堆

输入数组元素为:int arr[] = {3,1,4,1,5,9,2,6,5};

好啦,希望能够帮助到大家!

标签:arr,语言,实现,结点,右子,最小,int,数组,节点
From: https://blog.csdn.net/weixin_74009895/article/details/142520240

相关文章

  • sersync+rsync实现服务器文件实时同步
    sersync+rsync实现服务器文件实时同步一、为什么要用rsync+sersync架构?1、sersync是基于inotify开发的,类似于inotify-tools的工具2、sersync可以记录下被监听目录中发生变化的(包括增加、删除、修改)具体某一个文件或者某一个目录的名字,然后使用r......
  • 国庆节到了,扣子智能体coze画板功能实现贺卡编辑智能体自动添加logo和二维码,让海报品牌
    大家好,我是Shelly,一个专注于输出AI工具和科技前沿内容的AI应用教练,体验过300+款以上的AI应用工具。关注科技及大模型领域对社会的影响10年+。关注我一起驾驭AI工具,拥抱AI时代的到来。自媒体时代,不管是一个人、一个团队还是一家公司,都是一个IP。那么添加品牌的标志就是必不可少......
  • C语言课程设计题目(24个选题)
    C语言课程设计题目题目一:职工信息管理系统设计题目二:图书信息管理系统设计题目三:图书管理系统设计题目四:实验设备管理系统设计题目五:西文下拉菜单的设计题目六:学生信息管理系统设计题目七:学生成绩管理系统设计题目八:学生选修课程系统设计题目九:学生成绩记录簿设计题目十:......
  • 2024-09-25:用go语言,给定一个长度为 n 的整数数组 nums 和一个正整数 k, 定义数组的“能
    2024-09-25:用go语言,给定一个长度为n的整数数组nums和一个正整数k,定义数组的"能量"为所有和为k的子序列的数量之和。请计算nums数组中所有子序列的能量和,并对结果取模10^9+7后返回。输入:nums=[1,2,3],k=3。输出:6。解释:总共有5个能量不为0的子序列:子......
  • 面试官:项目中如何实现布隆过滤器?
    谈起“布隆过滤器”相信大家都不陌生,它也算日常面试中的常见面试题了。例如,当面试官在问到Redis模块的相关问题时,可能会问到缓存穿透(Redis四大经典问题之一),而缓存穿透的经典解决方案之一,则是“布隆过滤器”。但是,对于布隆过滤器是什么?以及布隆过滤器的实现原理?相信大部分同学......
  • TEDxDUTH 使用 NocoBase 实现革新
    作者:TEDxDUTHTEDxDUTH是由德莫克里特大学的志愿者们组成的一个充满活力的团队。作为TEDx全球社区的一员,我们的使命简单而有力:传播能够激励和引发改变的思想。我们通过精心策划一系列活动,成功汇聚了众多思想家、创新家以及行业领袖。我们的团队汇集了来自各个领域的热心志愿......
  • Linux 基础入门操作 第十章 多线程实现
    10线程介绍线程是进程的一条执行路径。每个线程共享其所附属的进程的所有的资源,包括打开的文件、页表(因此也就共享整个用户态地址空间)、信号标识及动态分配的内存等等。线程和进程的关系是:线程是属于进程的,线程运行在进程空间内,同一进程所产生的线程共享同一物理内存空间......
  • Flutter 自定义国家选择器:基于 A ~ Z字母索引的列表跳转与侧边栏导航实现
    在许多移动应用中,我们经常需要通过字母索引快速跳转到目标位置,比如通讯录、国家选择等功能。这篇博客将带大家实现一个仿照通讯录的Flutter国家选择器。通过一个字母索引的侧边栏,用户可以快速跳转到目标字母分组。效果:1.项目需求与设计思路我们需要实现一个包含多个国......
  • TEDxDUTH 使用 NocoBase 实现革新
    作者:TEDxDUTHTEDxDUTH是由德莫克里特大学的志愿者们组成的一个充满活力的团队。作为TEDx全球社区的一员,我们的使命简单而有力:传播能够激励和引发改变的思想。我们通过精心策划一系列活动,成功汇聚了众多思想家、创新家以及行业领袖。我们的团队汇集了来自各个领域的热心志愿者,我们......
  • 要实现在Vue 2中点击按钮后在新浏览器标签页中预览PDF文件 ,pdf文件默认放大125% 禁止P
    要在Vue2中实现点击按钮后在新浏览器标签页中预览PDF文件,并设置PDF文件默认放大125%以及禁止PDF的工具栏下载功能,你可以使用window.open方法,并在其中设置合适的URL参数来控制PDF查看器的行为。以下是一个实现的示例:创建Vue组件:在Vue组件中,添加一个按钮用于触发PDF预览......