追梦之旅【数据结构篇】——详解小白如何使用C语言实现堆数据结构
详解小白如何使用C语言实现堆数据结构 + “痛”撕堆排序~😎
- 前言🙌
- 什么是堆?
- 堆的概念及结构
- 堆的性质:
- 堆的实现
- 堆向下调整算法
- 画图分析:
- 堆向下调整算法源代码分享:
- 向下调整建小堆
- 向下调整建大堆
- 堆向上调整算法源代码分享:
- 画图分析:
- 向上调整建小堆
- 向上调整建大堆
- C语言整体实现堆数据结构源代码分享
- 堆的插入:
- 堆的删除:
- 画图分析:
- 头文件(Heap.h)编写:
- 功能文件(Heap.c)编写:
- 测试文件(test.c)编写:
- 运行结果测试截图:
- 总结撒花💞
😎博客昵称:博客小梦
😊最喜欢的座右铭:全神贯注的上吧!!!
😊作者简介:一名热爱C/C++,算法等技术、喜爱运动、热爱K歌、敢于追梦的小博主!
😘博主小留言:哈喽!😄各位CSDN的uu们,我是你的博客好友小梦,希望我的文章可以给您带来一定的帮助,话不多说,文章推上!欢迎大家在评论区唠嗑指正,觉得好的话别忘了一键三连哦!😘
前言🙌
哈喽各位友友们😊,我今天又学到了很多有趣的知识,现在迫不及待的想和大家分享一下!😘我仅已此文,手把手带领大家追梦之旅【数据结构篇】——详解小白如何使用C语言实现堆数据结构~ 都是精华内容,可不要错过哟!!!😍😍😍
什么是堆?
堆的概念及结构
如果有一个关键码的集合K = { , , ,…, },把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中,并满足:
- 父结点的值都大于孩子结点的值,则称为大堆;
- 父结点的值都小于孩子结点的值,则称为小堆;
大堆也称为大根堆,小堆也叫做小根堆。
堆的性质:
- 堆中某个节点的值总是不大于或不小于其父节点的值;
- 堆总是一棵完全二叉树。


堆的实现
堆向下调整算法
现在我们给出一个数组,逻辑上看做一颗完全二叉树。我们通过从根节点开始的向下调整算法可以把它调整成一个小堆。向下调整算法有一个前提:左右子树必须是一个堆,才能调整。
画图分析:


堆向下调整算法源代码分享:
向下调整建小堆
//向下调整--建小堆
void AdjustDown(int* a, int size, int parent)
{int child = parent * 2 + 1;while (child < size){if (child + 1 < size && a[child + 1] < a[child]){child++;}if (a[child] < a[parent]){Swap(&(a[parent]), &(a[child]));parent = child;child = parent * 2 + 1;}else{break;}}
}
向下调整建大堆
//建大堆
void AdjustDown(int* a, int size, int parent)
{int child = parent * 2 + 1;while (child < size){if (child + 1 < size && a[child + 1] > a[child]){child++;}if (a[child] > a[parent]){Swap(&(a[parent]), &(a[child]));parent = child;child = parent * 2 + 1;}else{break;}}
}
堆向上调整算法源代码分享:
画图分析:


向上调整建小堆
void AdjustUp(HPDataType* a, int child)
{assert(a);while (child > 0){int parent = (child - 1) / 2;if (a[child] < a[parent]){Swap(&(a[child]), &(a[parent]));child = parent;parent = (child - 1) / 2;}else{break;}}
}
向上调整建大堆
//向上调整建大堆
void AdjustUp(HPDataType* a, int child)
{assert(a);while (child > 0){int parent = (child - 1) / 2;if (a[child] > a[parent]){Swap(&(a[child]), &(a[parent]));child = parent;parent = (child - 1) / 2;}else{break;}}
}
C语言整体实现堆数据结构源代码分享
堆的插入:
先插入一个10到数组的尾上,再进行向上调整算法,直到满足堆。

void HeapPush(HP* php, HPDataType x)
{assert(php);//扩容if (php->capacity == php->size){int newcapacity = php->capacity == 0 ? 4 : php->capacity * 2;HPDataType* tem = (HPDataType*)realloc(php->a, sizeof(HPDataType) * newcapacity);if (tem == NULL){printf("realloc fail\n");exit(-1);}php->a = tem;php->capacity = newcapacity;}php->a[php->size] = x;//向上调整--建小堆if(php->size > 0)AdjustUp(php->a, php->size);php->size++;
}
堆的删除:
删除堆是删除堆顶的数据,将堆顶的数据和最后一个数据一换,然后删除数组最后一个数据,再进行向下调整算法。
画图分析:

void HeapPop(HP* php)
{assert(php);assert(!HeapEmpty(php));Swap(&(php->a[0]), &(php->a[php->size - 1]));php->size--;AdjustDwon(php->a, php->size,0);
}
头文件(Heap.h)编写:
#pragma once#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int HPDataType;typedef struct Heap
{HPDataType* a;int size;int capacity;
}HP;
void Swap(HPDataType* p1, HPDataType* p2);
// O(logN)
void AdjustDwon(HPDataType* a, int size, int parent);
void AdjustUp(HPDataType* a, int child);void HeapPrint(HP* php);
void HeapInit(HP* php);
void HeapDestroy(HP* php);
void HeapPush(HP* php, HPDataType x);
void HeapPop(HP* php);
HPDataType HeapTop(HP* php);
bool HeapEmpty(HP* php);
int HeapSize(HP* php);
功能文件(Heap.c)编写:
#define _CRT_SECURE_NO_WARNINGS 1#include"Heap.h"void Swap(HPDataType* p1, HPDataType* p2)
{int tem = *p1;*p1 = *p2;*p2 = tem;
}
// O(logN)
//建小堆
void AdjustDwon(HPDataType* a, int size, int parent)
{assert(a);int child = parent * 2 + 1;while (child < size){//选出最小的那个if (child + 1 < size && a[child + 1] < a[child]){child++;}if (a[child] < a[parent] ){Swap(&(a[parent]), &(a[child]));parent = child;child = parent * 2 + 1;}else{break;}}
}
void AdjustUp(HPDataType* a, int child)
{assert(a);while (child > 0){int parent = (child - 1) / 2;if (a[child] < a[parent]){Swap(&(a[child]), &(a[parent]));child = parent;parent = (child - 1) / 2;}else{break;}}
}void HeapPrint(HP* php)
{assert(php);for (int i = 0; i < php->size; i++){printf("%d ", php->a[i]);}printf("\n");
}
void HeapInit(HP* php)
{assert(php);php->a = NULL;php->capacity = php->size = 0;
}
void HeapDestroy(HP* php)
{assert(php);free(php->a);php->a = NULL;php->capacity = php->size = 0;
}
void HeapPush(HP* php, HPDataType x)
{assert(php);//扩容if (php->capacity == php->size){int newcapacity = php->capacity == 0 ? 4 : php->capacity * 2;HPDataType* tem = (HPDataType*)realloc(php->a, sizeof(HPDataType) * newcapacity);if (tem == NULL){printf("realloc fail\n");exit(-1);}php->a = tem;php->capacity = newcapacity;}php->a[php->size] = x;//向上调整--建小堆if(php->size > 0)AdjustUp(php->a, php->size);php->size++;}void HeapPop(HP* php)
{assert(php);assert(!HeapEmpty(php));Swap(&(php->a[0]), &(php->a[php->size - 1]));php->size--;AdjustDwon(php->a, php->size,0);
}HPDataType HeapTop(HP* php)
{assert(php);assert(!HeapEmpty(php));return php->a[0];
}
bool HeapEmpty(HP* php)
{assert(php);return php->size == 0;
}
int HeapSize(HP* php)
{assert(php);return php->size;
}
测试文件(test.c)编写:
#define _CRT_SECURE_NO_WARNINGS 1#include"Heap.h"void HeapTest1()
{HP h;HeapInit(&h);HeapPush(&h, 15);HeapPush(&h, 18);HeapPush(&h, 19);HeapPush(&h, 25);HeapPush(&h, 28);HeapPush(&h, 34);HeapPush(&h, 65);HeapPush(&h, 49);HeapPush(&h, 27);HeapPush(&h, 37);HeapPush(&h, 10);printf("%d\n", HeapSize(&h));HeapPrint(&h);for (int i = 0; i < 8; i++){printf("%d ", HeapTop(&h));HeapPop(&h);}printf("\n");HeapDestroy(&h);printf("%d ", HeapTop(&h));HeapPop(&h);
}int main()
{HeapTest1();return 0;
}
运行结果测试截图:

总结撒花💞
本篇文章旨在分享详解小白如何使用C语言实现堆数据结构。希望大家通过阅读此文有所收获!
😘如果我写的有什么不好之处,请在文章下方给出你宝贵的意见😊。如果觉得我写的好的话请点个赞赞和关注哦~😘😘😘
相关文章:
追梦之旅【数据结构篇】——详解小白如何使用C语言实现堆数据结构
详解小白如何使用C语言实现堆数据结构 “痛”撕堆排序~😎 前言🙌什么是堆?堆的概念及结构 堆的性质:堆的实现堆向下调整算法画图分析:堆向下调整算法源代码分享:向下调整建小堆向下调整建大堆 堆向上调整算…...
cocoscreator性能优化4-Sprite颜色数据去除
前言 Sprite是游戏内容的一个基本组成元素,包括ui、道具、立绘等各种地方都会用到。大部分情况下美术会帮我们调好图片颜色,我们只要把图片直接放到游戏里就行了。Sprite默认的渲染顶点数据中包含了颜色数据,由于我们并不需要去修改颜色&…...
系统接口幂等性设计探究
前言: 刚开始工作的时候写了一个带UI页面的工具,需要设计登录功能,登录功能也很简单,输入用户名密码点击登录,触发后台查询并比对密码,如果登录成功则返回消息给前端,前端把消息弹出提示一下。…...
C learning_7
目录 1.for循环 1.虽然while循环和for循环本质上都可以实现循环,但是它们在使用方法和场合上还是有一些区别的。 2.while循环中存在循环的三个必须条件,但是由于风格的问题使得三个部分很可能偏离较远,这样 查找修改就不够集中和方便。所以…...
PageRank算法介绍
互联网上有数百亿个网页,可以分为这么几类:不含有用信息的,比如垃圾邮件;少数人比较感兴趣的,但范围不是很广的,比如个人博客、婚礼公告或家庭像册;很多人感兴趣的并且十分有用的,比…...
springboot+vue职称评审管理系统(源码+文档)
风定落花生,歌声逐流水,大家好我是风歌,混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的职称评审管理系统。项目源码请联系风歌,文末附上联系信息 。 目前有各类成品java毕设,需要请看文末联系方式 …...
腾讯云4核8G轻量服务器12M支持多少访客同时在线?并发数怎么算?
腾讯云轻量4核8G12M轻量应用服务器支持多少人同时在线?通用型-4核8G-180G-2000G,2000GB月流量,系统盘为180GB SSD盘,12M公网带宽,下载速度峰值为1536KB/s,即1.5M/秒,假设网站内页平均大小为60KB…...
图片英文翻译成中文转换器-中文翻译英文软件
您正在准备一份重要的英文资料或文件,但是您还不是很熟练地掌握英文,需要翻译才能完成您的任务吗?哪个软件能够免费把英文文档翻译成中文?让我们带您了解如何使用我们的翻译软件来免费翻译英文文档为中文。 我们的翻译软件是一款功…...
月薪10k和40k的程序员差距有多大?
程序员的薪资一直是大家关注的焦点,相较于其他行业,程序员的高薪也是有目共睹的,而不同等级的程序员处理问题的方式与他们的薪资直接挂钩。 接下来就一起看一下月薪10k、20k、30k、40k的程序员面对问题都是怎么处理的吧! 场景一 …...
gateway整合knife4j(微服务在线文档)
文章目录 knife4j 微服务整合一、微服务与单体项目文档整合的区别二、开始整合1. 搭建一个父子maven模块的微服务,并引入gateway2.开始整合文档 总结 knife4j 微服务整合 由于单个服务的knife4j 整合之前已经写过了,那么由于效果比较好,然后微服务的项目中也想引入,所以开始微…...
ASP.NET 记录 HttpRequest HttpResponse HttpServerUtility
纯属个人记录,会有错误 HttpRequest Browser是获取客户端浏览器的信息 Cookies是获取客户端的Cookies QueryString是获取客户端提交的数据 ServerVariables是获取服务器端或客户端的环境变量信息 Browser 语法格式: Request.Browser[“浏览器特性名”] 常见的特性名 名称说…...
Python 人工智能:11~15
原文:Artificial Intelligence with Python 协议:CC BY-NC-SA 4.0 译者:飞龙 本文来自【ApacheCN 深度学习 译文集】,采用译后编辑(MTPE)流程来尽可能提升效率。 不要担心自己的形象,只关心如何…...
辉煌优配|军工板块逆市上涨,16只概念股已披露一季度业绩预喜
今日,军工股逆市上涨。 4月21日,A股三大股指低开低走,半导体、AI使用、信创工业、软件等科技属性概念领跌,国防军工、食品饮料和电力设备等板块上涨。 工业互联网中心工业规模超1.2万亿元 据央视新闻报道,本年是《工业…...
看板与 Scrum:有什么区别?
看板和Scrum是项目管理方法论,以小增量完成项目任务并强调持续改进。但是他们用来实现这些目标的过程是不同的。看板以可视化任务和连续流程为中心,而Scrum更多是关于为每个交付周期实施时间表和分配设定角色。 在看板和Scrum之间做出选择并不总是必要…...
零代码是什么?零代码平台适合谁用?
随着信息技术的发展,软件开发领域也不断发生变革,零代码(No-Code)开发模式越来越受到关注。 零代码到底是什么,能不能用通俗的话来说?这就来给大家讲一讲! 01 零代码为什么出现? 随…...
CNStack 云服务云组件:打造丰富的云原生技术中台生态
作者:刘裕惺 CNStack 相关阅读: CNStack 多集群服务:基于OCM 打造完善的集群管理能力 CNStack 虚拟化服务:实现虚拟机和容器资源的共池管理 CNStack 云边协同平台:实现原生边缘竟能如此简单 01 前言 CNStack 2.0…...
#PythonPytorch 1.如何入门深度学习模型
我之前也写过一篇关于Keras的深度学习入门blog,#Python&Keras 1.如何从无到有在自己的数据集上实现深度学习模型(入门),里面也有介绍了一下一点点机器学习的概念和理解深度学习的输入,如果对这方面有疑惑的朋友可以…...
[API]节点流和处理流字节流和字符流(七)
java将流分为节点流和处理流两类: 节点流:也称为低级流,是真实连接程序和另一端的"管道",负责实际读写数据的流,读写一定是建立在节点流的基础之上进行的。节点流好比家里的"自来水管",…...
开心档之C++ 模板
C 模板 目录 C 模板 函数模板 实例 类模板 实例 模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码。 模板是创建泛型类或函数的蓝图或公式。库容器,比如迭代器和算法,都是泛型编程的例子,它们都使用…...
拥抱还是革命,ChatGPT时代 AI专家给出15条科研生存之道
来源:专知 微信号:Quan_Zhuanzhi 你是学术机构的人工智能研究员吗?你是否担心自己无法应对当前人工智能的发展步伐?您是否觉得您没有(或非常有限)访问人工智能研究突破所需的计算和人力资源?你并不孤单; 我们有同样的感觉。越来越多的人工智能学者不…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
比较数据迁移后MySQL数据库和OceanBase数据仓库中的表
设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...
Chrome 浏览器前端与客户端双向通信实战
Chrome 前端(即页面 JS / Web UI)与客户端(C 后端)的交互机制,是 Chromium 架构中非常核心的一环。下面我将按常见场景,从通道、流程、技术栈几个角度做一套完整的分析,特别适合你这种在分析和改…...
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么?它的作用是什么? Spring框架的核心容器是IoC(控制反转)容器。它的主要作用是管理对…...
算术操作符与类型转换:从基础到精通
目录 前言:从基础到实践——探索运算符与类型转换的奥秘 算术操作符超级详解 算术操作符:、-、*、/、% 赋值操作符:和复合赋值 单⽬操作符:、--、、- 前言:从基础到实践——探索运算符与类型转换的奥秘 在先前的文…...
2.2.2 ASPICE的需求分析
ASPICE的需求分析是汽车软件开发过程中至关重要的一环,它涉及到对需求进行详细分析、验证和确认,以确保软件产品能够满足客户和用户的需求。在ASPICE中,需求分析的关键步骤包括: 需求细化:将从需求收集阶段获得的高层需…...
HTML版英语学习系统
HTML版英语学习系统 这是一个完全免费、无需安装、功能完整的英语学习工具,使用HTML CSS JavaScript实现。 功能 文本朗读练习 - 输入英文文章,系统朗读帮助练习听力和发音,适合跟读练习,模仿学习;实时词典查询 - 双…...

