堆(C语言)

2023-05-16

文章目录

  • 堆(heap)
    • 什么是堆
    • 最小堆的操作
    • 操作集的实现(C语言)


堆(heap)

什么是堆

  1. 定义

    堆(heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。

  2. 性质

    1. 结构性:用数组表示的完全二叉树。
    2. 有序性:任意节点的关键字(权值)是其子树所有节点的最大值(或最小值)
      • 父节点大于子节点:最大堆(MaxHeap)
      • 父节点小于子节点:最小堆(MinHeap)
  3. 应用

    1. 优先队列

      “优先队列” (Priority Queue)是特殊的“队列”,从队列中取出元素的顺序是依照元素的优先权(关键字)大小,而不是元素进入队列的先后顺序。

    2. 堆排序
  4. 举例

    1. 堆:最大堆或最小堆
      堆的例子
    2. 不是堆:不是完全二叉树或节点权值不符合要求
      不是堆的例子

最小堆的操作

  1. 数据名称:最小堆(MinHeap)
  2. 数据对象集
    一个有 N > 0 N \gt 0 N>0个元素的最小堆是一棵完全二叉树,每个节点上的元素值不大于其子节点元素的值。
  3. 操作集
    对于任意最多有MaxSize个元素的最小堆 H ∈ M i n H e a p H \in MinHeap HMinHeap元素 i t e m ∈ E l e m e n t T y p e item \in ElementType itemElementType,主要操作有:
    1. MinHeap Create(int Maxsize): 创建一个空的最小堆。
    2. void Destroy(MinHeap):释放堆的空间。
    3. Boolean IsFull(MinHeap H): 判断最小堆是否已满。
    4. Boolean IsEmpty(MinHeap H): 判断最小堆是否为空。
    5. void Insert(MinHeap H,ElementType item): 将元素item插入最小堆H。
    6. ElementType DeleteMin(MinHeap H): 返回最小堆H中最小元素(高优先级)。

操作集的实现(C语言)

  1. 数组表示的完全二叉树
    数组下标为0的位置放一个比所有堆中元素都要小的元素(可以是ElementType的最小值),称为“哨兵”。从下标为1的位置开始存放堆中元素。因为是完全二叉树,所以父亲节点与其左右子节点下标满足一些关系。
    例:
    用数组表示完全二叉树
    由子节点找父节点:父节点下标=子节点下标 / 2
    由父节点找左子节点:左子节点下标=父节点下标 * 2
    由父节点找右子节点:右子节点下标=父节点下标 * 2 + 1

  2. 存储结构

    typedef struct HeapStruct{
      ElementType *Element; /* 存储堆元素的数组 */
      int Size; /* 堆的当前元素个数(最后一个元素的下标) */
      int MaxSize; /* 堆存储空间的大小 */
    }HeapStruct,*MinHeap;
    
  3. 操作集的实现

    1. MinHeap Create(int MaxSize): 创建一个空的最小堆

      MinHeap Create(int MaxSize)
      {
        MinHeap H = (MinHeap)malloc(sizeof(struct HeapStruct));//分配堆结构空间
        H->Elenment = (ElementType *)malloc((MaxSize + 1) * sizeof(ElementType));//分配储存堆元素的数组的空间
        H->Size = 0;
        H->MaxSize=MaxSize;
        H->Elenment[0] = INT_MIN;//数组第一个元数放最小元素,数组第二个元素放堆中最小元素
      
        return H;
      }
      
    2. void Destroy(MinHeap H): 释放堆申请的空间

      void Destroy(MinHeap H)
      {
        free(H->Elenment);//先释放堆节点的数组空间
        free(H);//再释放堆节点的空间
      }
      
    3. boolean IsFull(MinHeap H): 判断最小堆是否已满

      boolean IsFull(MinHeap H)
      {
        return (H->Size == H->MaxSize);//判断最小堆中元素个数Size是否等于最大容量MAXSIZE。
      }
      
    4. boolean IsEmpty(MinHeap H): 判断最小堆是否为空

      boolean IsEmpty(MinHeap H)
      {
        return (H->Size == 0);//判断堆中元素个数是否等于0
      }
      
    5. void Insert(MinHeap H,ElementType item): 将元素item插入最小堆H

      //将元素item插入堆H
      void Insert(MinHeap H, ElementType item)
      {
        int i = 0;
      
        //判断堆H是否已满
        if (IsFull(H))
        {
          printf("Heap is full\n");
          return;
        }
      
        /*
        如果H未满,将item放入堆最后一个元素,查看它的父节点,如果它的父节点比它大,将它和它的父节点互换位置,
        循环此过程,直至它的父节点小于它。可能它比所有它的父节点都要小,但是一定会比哨兵大(数组中下标为0的位置),
        所以一定最后它的下标一定大于哨兵的下标0。这就是哨兵的意义。
        */
        H->Size++;
        for (i = H->Size; H->Element[i / 2] > item; i = i / 2)
        {
          H->Element[i] = H->Element[i / 2];
        }
        H->Element[i] = item;
      }
      
    6. ElementType Delete(MinHeap H): 返回最小堆H中最小元素(高优先级)

      //将堆根节点元素取出,并将堆元素重新排序
      ElementType Delete(MinHeap H)
      {
        int parent=0,child=0;
        ElementType item,temp;
      
        //判断堆是否已经空了
        if (IsEmpty(H))
        {
          printf("Heap is Empty\n");
          return H->Element[0];
        }
      
        /*
        堆没有空,将根节点返回,最后一个叶子节点放到根节点位置,然后比较它与它的左右子节点中最小
        节点的大小,如果它比较大,则将它和它的较小的子节点互换位置,重复此过程,直至他比两个子节点
        都小或者它不在有子节点
        */
        item = H->Element[1];
        temp = H->Element[H->Size];
        H->Size--;
        for (parent = 1; parent *2 <= H->Size; parent = child)
        {
          child = parent *2;
          //找出左右子节点最小的那个
          if (child != H->Size && (H->Element[child] > H->Element[child + 1]))
          {
            child++;
          }
          //比较它与最小的子节点的大小,如果它比较大,则两者互换位置,否则跳出循环
          if (temp > H->Element[child])
          {
            H->Element[parent] = H->Element[child];
          }
          else
          {
            break;
          }
        }
        H->Element[parent] = temp;
        return item;
      }
      
    7. MinHeap BuildMinHeap(ElementType *Elenment, int Size): 创建一个非空的堆

      已知堆中元素,但是不知道其在数组中的排列顺序,可以有两种创建堆的方法:一是先创建一个空堆,再使用Insert()函数将元素一个个插入堆中。二是直接将数组复制到堆节点的Element数组中,然后进行排序。

      第二种方法比第一种方法时间复杂度更低。

      //已知一个数组,创建一个由数组元素组成的最小堆
      MinHeap BuildMinHeap(ElementType *Element, int Size,int MaxSize)
      {
        MinHeap H = NULL;
        int i = 0, parent = 0, child = 0;
        ElementType Temp;
      
        //创建一个空最小堆
        H = CreateMinHeap(MaxSize);
      
        //判断存储空间是否够用
        if (Size > H->MaxSize)
        {
        	printf("最小堆存储空间不足,建立最小堆失败\n");
        	return NULL;
        }
      
        //将数组中元素复制到存储最小堆元素的数组里
        for (i = 0; i < Size; i++)
        {
        	H->Element[i + 1] = Element[i];
        }
        H->Size = Size;
      
        //给最小堆存储空间中元素排序
        /*
        最后一个节点的父节点的左右指针都指向一个堆,将最后一个节点的父节点和它的两个子节点排序(方法类似
        与删除节点的操作),使得最后一个节点、其父节点和其兄弟节点形成一个堆。循环操作,从最后一个节点的
        父节点往上依次执行这个操作,最后使得整个树都是一个堆。
        */
        for (parent = H->Size / 2; parent >= 1; parent--)
        {
        	Temp = H->Element[parent];
        	for (; parent * 2 <= H->Size; parent = child)
        	{
        		child = parent * 2;//child为parent左子树的下标,(child+1)为右子树下标
      
        		//如果左右子树都存在,且左子树大于右子树的值,将child作为两者较小者的下标
        		if (child != H->Size && (H->Element[child] > H->Element[child + 1]))
        		{
        			child++;
        		}
      
        		//比较parent指向的节点与child指向节点的大小,parent较大则两者互换位置
        		if (Temp > H->Element[child])
        		{
        			H->Element[parent] = H->Element[child];
        		}
        		else
        		{
        			break;
        		}
        	}
        	H->Element[parent] = Temp;
        }
      
        return H;
      }
      
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

堆(C语言) 的相关文章

  • 金融系统-基金管理

    金融系统 基金管理 本项目为携投基金系统 xff0c 在客户端浏览器输入网址 xff0c 即可载入该系统 xff0c 本系统采用当前主流前端开发语言有 xff1a layui js等前端主流技术 采用的后端开发语言框架等有 xff1a SS
  • 学校教材管理系统-毕设、课设(最佳参考)

    下载地址 高校教材管理系统 项目介绍 基于springboot 43 mybatis 43 jwt 43 layui 43 mybatis 43 html 43 javaScript的用于高校管理教材的系统 项目主要功能 教材信息管理 教材
  • android-校园拍卖管理系统-毕设课设-含源码

    校园拍卖系统 android 源码私信 xff0c 有回必应 xff0c 三连关注 xff0c 免费 xff01 xff01 xff01 android实现校园拍卖系统 xff0c 使用语言为java xff0c 工具idea或者andro
  • ChatGPT 未来的前景以及发展趋势

    当谈到ChatGPT的未来和发展趋势时 xff0c 需要考虑人工智能技术以及文本生成和交互的迅速发展 在这方面 xff0c ChatGPT的前景非常有希望 xff0c 因为它是一种迄今为止最先进的人工智能技术之一 ChatGPT是一种基于机
  • 同步FIFO 两种方法

    RAM 43 空满信号判断 xff0c 两种方法 一 空满标志用指针位置得到 二 空满标志用fifo的中数据的计数得到 一 当写指针超过读指针一圈 xff0c 写满 xff1b 写指针等于读指针 xff0c 读空 96 timescale
  • linux内核串口日志抓取-minicom工具使用方法

    linux抓串口日志 抓串口日志方式minicom保存串口日志log抓取主板串口日志minicom man手册 抓串口日志方式 1 xff09 问题机上 xff0c 找到串口设备 xff0c 比如 dev ttyAMA 0 1 2 3 st
  • 二叉树(七):二叉树的高度与平衡二叉树

    一 二叉树的深度与高度 1 二叉树的深度 对于二叉树中的某个节点 xff0c 其深度是从根节点到该节点的最长简单路径所包含的节点个数 xff0c 是从上面向下面数的 因此访问某个节点的深度要使用先序遍历 2 二叉树的高度 对于二叉树中的某个
  • Python --语法自纠

    文章目录 1 输入2 数据类型转换 xff0c 字符串3 字典 xff0c 列表 xff0c 元组4 语法0 错题 1 输入 输入eval作用一次输入一个或多个 map print format m n format输出 2 数据类型转换
  • 强化学习算法复现(六):DoubleDQN_gym倒立摆

    建立RL brain py span class token keyword import span torch span class token keyword import span torch span class token pun
  • Android的控件绑定----ViewBinding

    在Android开发中 xff0c 控件的绑定是开发者无法绕开的一道程序 是Android开发中最原始 xff0c 也是最基础的一种获取View的方法 在一个复杂布局的页面时 xff0c 我们要一个个控件去调用findViewById方法去
  • C++ OpenCV CV_***未声明的标识符的解决办法

    1 OpenCV cvtColor CV BGR2GRAY未声明的标识符的解决办法 加上这个引用即可 include lt opencv2 imgproc types c h gt 2 opencv里面CV FOURCC找不到标识符 CV
  • 多线程-生产者和消费者模式

    1 简单实现多线程 多线程是多任务处理的一种特殊形式 xff0c 多线程处理允许让一个进程中同时运行两个或两个以上的线程 这样的话 xff0c 能更加充分发挥计算机的性能 xff0c 并高效完成用户的任务 多线程实现的三步骤 xff1a 第
  • HTML网页注册图片

    lt DOCTYPE html gt lt html gt lt head gt lt meta charset 61 34 utf 8 34 gt lt title gt lt title gt lt style type 61 34 t
  • [WAX云钱包】解决Cloudflare通过SSL指纹识别实现的反爬虫机制

    WAX云钱包 在之前的多篇文章中 xff0c 我们使用 Python 43 Selenium 来实现WAX链游脚本 xff0c 主要是因为很多玩家一开始都是用WAX云钱包注册的账号 xff0c 而WAX云钱包的私钥托管在云端 xff0c 我
  • 小狼毫[rime_win][眀月拼音]简单配置方法

    小狼毫 rime win 朙月拼音 简单配置方法 我自己的配置文件 当配置后 需要重新部署后设置才能生效 需要修改的文件 需要修改 增加的文件均在用户文件夹下 用户文件夹可以通过右键输入法状态栏的图标后点击用户文件夹到达 修改 增加的文件名
  • 生产者消费者模式(c++)

    什么是生产者消费者模式 xff1f 想象一下 xff0c 你早上起来肚子快饿扁了 xff0c 去包子铺买包子 xff0c 包子铺有三个人在做包子 xff08 也可以是一个 xff09 xff0c 这些人就是生产者 xff0c 你作为买包子的
  • go语言interface转string、bool、int

    在go语言中interface转string可以直接使用fmt提供的fmt函数 xff0c 而转bool和int则是在string的基础上来进行转换 xff0c 详见如下代码 func Get f string value interfac
  • centos7中启动juoyter notebook后,复制链接无法打开网页

    centos7中启动juoyter notebook后 xff0c 复制链接无法打开网页 xff0c 一直停留在如下界面 xff1a 解决办法 xff1a 这需要在Linux浏览器中打开 在windows中无法打开 xff0c 若没有安装l
  • 数据结构——BF, KMP

    文章目录 1 串的基本操作2 串的BF模式 朴素的模式匹配 暴力匹配 定位操作 3 串的KMP模式匹配 定位操作 1 规则 xff1a 2 举例 xff1a 3 采用以空间换时间策略 xff0c 操作方法如下 xff1a 4 操作举例 xf
  • linux如何在界面和终端的不同模式下运行pyspark?

    一 xff0c 界面打开 1 直接输入jupyter notebook后打开界面 查看运行模式 xff1a 输入sc master 若输出为 xff1a local xff0c 则表示它是在本地模式下运行 2 xff0c 如何使用jupyt

随机推荐

  • 官网下载eclipse太慢解决办法及jdk版本要求

    1 Eclipse 4 6 Neon 需要JDK1 8版本 2 Eclipse 4 5 Mars 需要JDK1 7及以上版本 3 Eclipse 4 4 Luna 需要JDK1 7及以上版本 4 Eclipse 4 3 Kepler 需要J
  • Ubuntu中Pycharm快捷方式只能以sudo sh pycharm.sh运行,双击快捷方式没反应怎么办?

    创建pycharm快捷方式的博客文章很多 xff0c 我找了很久才解决我的问题 xff0c 这里主要参考这篇 xff1a 链接 link 主要问题 双击pycharm快捷方式没反应 xff0c 只能在终端中用sudo sh pycharm
  • Gazebo上帝视角里程计 get_model_state 绝对里程计

    Gazebo model states Gazebo有一个服务 gazebo get model state 和一个话题 gazebo model states 来反馈model的状态 服务 gazebo get model state 话
  • 【GaussDB数据库----连接】

    1 确认连接信息 客户端工具通过CN连接数据库 因此连接前 xff0c 需获取CN所在服务器的IP地址及CN的端口号信息 客户端工具可以通过任何一个CN连接数据库 以操作系统用户omm登录安装有MPPDB服务的任一主机 执行source B
  • 天干地支(出生年月的转换)

    十 天干 xff1a 甲 xff08 ji xff09 乙 xff08 y xff09 丙 xff08 b ng xff09 丁 xff08 d ng xff09 戊 xff08 w xff09 己 xff08 j xff09 庚 xff0
  • http转https后资源加载失败的解决方案

    之前没给域名加SSL证书的时候 xff0c 项目好好的 xff0c icon图标还有 xff0c 给域名了SSL证书后 xff0c icon图标就不在了 原因就是因为项目本身采用http的资源文件 xff0c 换成https后就不解析这些资
  • Docker 安装 Redis + Spring Boot 整合 Redis

    Docker安装Redis 一 启动docker容器 systemctl start docker 二 拉取redis镜像 docker pull redis 三 端口映射 docker run name redis p 6379 6379
  • 如何保证缓存与数据库数据一致性

    redis系列之数据库与缓存数据一致性解决方案 重点文章 xff1a https www cnblogs com cxxjohnson p 8519616 html 你只要用缓存 xff0c 就可能会涉及到缓存与数据库双存储双写 xff0c
  • 2020年:maven配置最新阿里云镜像,以及在IDEA中的设置

    记得当初学习Maven的时候 xff0c 由国外的中央仓库切换为阿里云镜像之后 xff0c 用起来是辣么地丝滑 不过最近一段时间 xff0c Maven却总是出现一些问题 xff0c 本地库里也总是出现一些 lastUpdated文件 xf
  • Node.js—— MySQL(第三方API ),web开发模式

    文章目录 0 目标1 数据库 xff08 数据库管理系统 xff09 2 MySQL3 SQL语句1 基本语句2 js 操作数据库中的查询 xff0c 增加 xff0c 更新 xff08 改 xff09 xff0c 删除 3 MYSQL操作
  • 实现生产者消费者模式的三种方式

    什么是生产者消费者模式 简单来说 xff0c 生产者消费者模式就是缓冲区 那么这么做有两个好处 xff0c 一个是解耦 xff0c 第二个是平衡生产能力和消费能力的差 xff0c 因为生产者和消费者的速度是不一样的 xff0c 有了这个缓冲
  • Go语言Windows10安装和环境配置详细步骤

    文章目录 前言一 下载Go安装包 xff1f 二 安装步骤1 安装2 验证是否安装成功 环境配置1 环境配置准备1 配置步骤 前言 提示 xff1a 我用的是windows10系统 xff1a 例如 xff1a Go安装包下载和在windo
  • C语言中scanf、gets、fgets,C++中cin、getline读取字符串的效率比较

    转自 xff1a https blog csdn net richenyunqi article details 89203826 可以使用C语言中scanf gets fgets xff0c C 43 43 中cin getline函数读
  • Android.mk和Android.bp的语句转换

    编译不同类型的模块 编译成 Native 动态库 Android mk include BUILD SHARED LIBRARY Android bp cc library shared 编译成 Native 静态库 Android mk
  • 学习c/c++ 推荐学习什么书籍?

    学习编程包含以下几个重要方面 xff1a 了解语言的语法 知道那些特性可以使用和何时使用 写出可读性好的代码 编译器可以理解 xff0c 但是下一个人是否可以阅读呢 xff1f 在一个更高层次设计结构良好的程序 为了学习一门语言 xff0c
  • 深入理解 http 反向代理(nginx)

    要理解什么是 反向代理 reverse proxy 自然你得先知道什么是 正向代理 forward proxy 另外需要说的是 一般提到反向代理 通常是指 http 反向代理 但反向代理的范围可以更大 比如 tcp 反向代理 在这里 不打算
  • 01-【Royal TSX】Mac上最好用的SSH工具Royal TSX使用教程

    参考文章 xff1a https www jianshu com p 0206980f529e
  • 数据结构:线性结构(C语言)

    文章目录 线性结构线性表什么是线性表线性表的抽象类型描述线性表的实现 广义表广义表定义多重链表 堆栈什么是堆栈堆栈的抽象数据类型描述堆栈的顺序存储实现堆栈的链式存储实现堆栈的应用 队列什么是队列队列的抽象数据类型描述队列的顺序存储实现队列的
  • 树(C语言)

    文章目录 树树的定义树的一些基本术语树的表示 树 树的定义 树 xff08 Tree xff09 xff1a n n 0
  • 堆(C语言)

    文章目录 堆 heap 什么是堆最小堆的操作操作集的实现 C语言 堆 heap 什么是堆 定义 堆 heap 是计算机科学中一类特殊的数据结构的统称 堆通常是一个可以被看做一棵树的数组对象 性质 结构性 xff1a 用数组表示的完全二叉树