【C语言】数据结构#实现堆


目录

(一)堆

(1)堆区与数据结构的堆

(二)头文件

(三)功能实现

 (1)堆的初始化

(2)堆的销毁

(3)插入数据

(4)删除堆顶的数据        

(5)得到堆顶的数据

(6)判断堆是否为空

(7)得到堆内数据个数


正文开始:

(一)堆

(1)堆区与数据结构的堆

          堆区和数据结构中的堆是两个不同的概念。

       

  1. 堆区 (Heap) :堆区是计算机内存中的一部分,用于存储动态分配的内存空间。在程序运行时,堆区用于存储使用 new 或 malloc 等方法分配的内存空间,在程序运行结束后,由程序员手动释放。堆区是一块较大的内存区域,用于存储动态分配的数据。堆区的大小可以动态增长或缩小,具有较高的灵活性。堆区的访问速度较慢,但能够存储较大的数据。

  2. 数据结构中的堆:在数据结构中,堆是一种特殊的树状结构,具有以下特点:

  • 堆是一个完全二叉树,即除了最底层外,其他层都是满的,最底层的结点从左到右连续排列。
  • 堆中的每个结点的值都大于等于(或小于等于)其子结点的值,根结点是树中最大(或最小)的结点。
  • 堆可以分为最大堆和最小堆,最大堆的根结点是整个堆中最大的元素,最小堆的根结点是整个堆中最小的元素。

        

         在数据结构中,堆通常用于实现优先队列(Priority Queue)和堆排序(Heap Sort)等算法。堆的插入和删除操作的时间复杂度都为 O(log n),其中 n 是堆中元素的个数。

(二)头文件

        STL(Standard Template Library)是C++标准库中的一个组件,提供了一系列的通用数据结构和算法,以及一些函数模板,用于简化C++程序的开发。STL包括了容器(Containers)、算法(Algorithms)和迭代器(Iterators)三个主要部分。

  1. 容器(Containers):STL提供了多种容器,包括向量(vector)、链表(list)、双端队列(deque)、集合(set)、映射(map)等。这些容器提供了不同的数据结构和操作,方便了数据的存储和处理。

  2. 算法(Algorithms):STL提供了一系列的算法,包括排序、查找、合并、变序、计数等等。这些算法可以对容器中的元素进行操作,使得程序更加高效和简洁。

  3. 迭代器(Iterators):STL的迭代器是一个泛型指针,用于遍历容器中的元素。迭代器提供了一种统一的访问容器元素的方式,使得算法可以独立于容器而使用。

        本文根据Cpp的STL来实现堆的功能,包括堆的初始化,销毁,插入数据,删除堆顶的数据,得到堆顶的数据,判断堆是否为空,得到堆内数据个数等七个功能接口。

        本文基于顺序表实现堆;

        这里不加解释的给出头文件,根据头文件实现堆的功能:

        命名:Heap.h

#pragma once#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>typedef int HPDatatype;typedef struct Heap
{HPDatatype* a;//存储数据的数组int size;     //堆内数据的个数int capacity; //顺序表的容量
}HP;//初始化
void HPinit(HP* php);//销毁
void HPDestroy(HP* php);//插入数据
void HPpush(HP* php, HPDatatype x);//删除数据,规定删除堆顶的数据
void HPpop(HP* php);//得到堆顶数据
HPDatatype HPtop(HP* php);//判空
bool HPempty(HP* php);//数据个数
int HPsize(HP* php);

         

(三)功能实现

 (1)堆的初始化

堆的初始化

        首先,函数接收的指针(被传入的地址)不为空(否则无法进行解引用操作),通过assert断言实现;

        将数组置空,顺序表的大小与容量置0;


//初始化
void HPinit(HP* php)
{assert(php);php->a = NULL;php->capacity = php->size = 0;
}

 

(2)堆的销毁

堆的销毁

          首先,函数接收的指针(被传入的地址)不为空(否则无法进行解引用操作),通过assert断言实现;

        释放掉动态申请的顺序表内的数组,顺序表的大小与容量置0;


//销毁
void HPDestroy(HP* php)
{assert(php);free(php->a);php->capacity = php->size = 0;}

 

(3)插入数据

 

插入数据

         首先,函数接收的指针(被传入的地址)不为空(否则无法进行解引用操作),通过assert断言实现;

        其次判断数组内数据是否满了

        ——如果顺序表容量等于数组的大小,代表数据满了,那么进行扩容。Newcapacity的赋值通过三目操作符实现:如果capacity为初始值0,Newcapacity赋值为4,否则赋值为2*capacity。如果realloc申请失败,打印错误信息并返回。若申请成功,压入数据。

        ——如果数据没有满,直接在数组中插入数据,由于插入的数据不一定与原数据成堆,所以要进行向上调整

        调整需要交换,于是提前给出交换的功能接口:

 交换

//传址交换
void Swap(HPDatatype* p1, HPDatatype* p2)
{HPDatatype tem = *p1;*p1 = *p2;*p2 = tem;
}

 

 什么是向上调整?

         堆在逻辑上是二叉树,在物理上实际上是数组,数组的下标如下:

         在堆中,有一个规律:

  •         父节点下标 = (子节点下标 - 1) / 2;
  •         左子节点下标 = (父结点下标  * 2) + 1;
  •         右子节点下标 = (父结点下标  * 2) + 2;

        于是,我们可以通过一个节点的下标,找到他的父和子的下标 ;

本文以实现小堆为例 

向上调整

        将新插入的节点与其父节点比较,如果新节点小于父结点,两节点交换值,继续迭代进行;

         直到新节点的值大于等于父结点,或者已经比到了根节点才停止;


//push实现小堆的向上调整
void AdgustUP(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 = (child - 1) / 2;}else{break;}}
}

 

 插入数据

 


//插入数据
void HPpush(HP* php, HPDatatype x)
{assert(php);//数据满,realloc扩容,得到新的大容量顺序表if (php->capacity == php->size){int Newcapacity = php->capacity == 0 ? 4 : php->capacity * 2;HPDatatype* tem = (HPDatatype*)realloc(php->a, Newcapacity * sizeof(HPDatatype));if (tem == NULL){perror("realloc fail!");return;}php->a = tem;php->capacity = Newcapacity;}//数据不满,直接插入php->a[php->size] = x;php->size++;//向上调整AdgustUP(php->a,php->size-1);
}

 

(4)删除堆顶的数据        

删除数据

        删除数据规定的是删除堆顶的数据;

        函数接收的指针(被传入的地址)不为空(否则无法进行解引用操作),通过assert断言实现;

        如何删除?

        -直接删除,由于二叉树的兄弟节点是没有大小关系的,如果直接删除根节点,那么所有节点的下标减一,这意味着原来的的二叉树的结构就被完全破坏了,接下来只能重新建堆,代价太大。

        -先交换堆顶与最后一个数据,然后删除最后一个数据(其实就是原堆顶数据),然后进行向下调整;

        这样既没有完全破换二叉树的结构,只有一个数据需要调整位置,又操作简便只需size--即可。

向下调整

        思路与向上调整基本一致;


//小堆向下调整——找小
void AdgustDown(HPDatatype* a, int n, int parent)
{//假设左孩子小int child = parent * 2 + 1;while (child < n){//如果右孩子小,假设不成立if (child + 1 < n && a[child] > a[child + 1]){child++;}//此时,child表示较小的孩子if (a[child] < a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}}

删除数据


//删除数据,规定删除堆顶的数据
void HPpop(HP* php)
{assert(php);//交换堆顶与最后一个数据Swap(&php->a[0], &php->a[php->size - 1]);//删除堆顶的数据php->size--;//向下调整AdgustDown(php->a, php->size,0);}

(5)得到堆顶的数据

          首先,函数接收的指针(被传入的地址)不为空(否则无法进行解引用操作),通过assert断言实现;

        其次,堆不为空,通过assert断言实现;

        直接返回堆顶的数据即可;


//得到堆顶数据
HPDatatype HPtop(HP* php)
{assert(php);assert(!HPempty(php));return php->a[0];
}

 

(6)判断堆是否为空

         首先,函数接收的指针(被传入的地址)不为空(否则无法进行解引用操作),通过assert断言实现;

         直接返回判断表达式的值即可;(若为空,返回真(1);否则返回假(0))

//判空
bool HPempty(HP* php)
{assert(php);return php->size == 0;
}

 

(7)得到堆内数据个数

          首先,函数接收的指针(被传入的地址)不为空(否则无法进行解引用操作),通过assert断言实现;

        直接返回堆内数据个数即可;


//数据个数
int HPsize(HP* php)
{assert(php);return php->size;
}


完~

未经作者同意禁止转载 

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

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

相关文章

快速部署MES源码/万界星空科技开源MES

什么是开源MES软件&#xff1f; 开源MES软件是指源代码可以免费获取、修改和分发的MES软件。与传统的商业MES软件相比&#xff0c;开源MES软件具有更高的灵活性和可定制性。企业可以根据自身的需求对软件进行定制化开发&#xff0c;满足不同生产环境下的特定需求。 开源MES软件…

稳压二极管应用电路

稳压二极管比较特殊&#xff0c;基本结构与普通二极管一样&#xff0c;也有一个PN结。由于制造工艺的不同&#xff0c;当这种PN结处于反向击穿状态时&#xff0c;PN结不会损坏(普通二极管的PN结是会损坏)&#xff0c;在稳压二极管用来稳定电压时就是利用它的这一击穿特性。 由…

串行通信的艺术:深入解析UART与奇偶校验

发送数据位是电流传输吗&#xff1f; 在UART&#xff08;Universal Asynchronous Receiver/Transmitter&#xff09;通信中&#xff0c;发送数据位不直接以电流的形式传输。而是通过改变电压水平或者光信号&#xff08;在光纤通信中&#xff09;来表示不同的数据位&#xff08…

中小学信息学奥赛CSP-J认证 CCF非专业级别软件能力认证-入门组初赛模拟题第二套(阅读程序题)

CSP-J入门组初赛模拟题二 二、阅读程序题 (程序输入不超过数组或字符串定义的范围&#xff0c;判断题正确填√错误填X;除特殊说明外&#xff0c;判断题 1.5分&#xff0c;选择题3分&#xff0c;共计40分) 第一题 1 #include<bits/stdc.h> 2 using namespace std; 3 i…

探索微信小程序的奇妙世界:从入门到进阶

文章目录 一、什么是微信小程序1.1 简要介绍微信小程序的定义和特点1.2 解释小程序与传统应用程序的区别 二、小程序的基础知识2.1 微信小程序的架构2.2 微信小程序生命周期的理解2.3 探索小程序的目录结构和文件类型 三、小程序框架和组件3.1 深入了解小程序框架的核心概念和原…

【无标题】Matlab之annotation函数——创建图形注释(箭头、椭圆、矩形)

应用1&#xff1a;创建文本箭头注释 创建一个简单线图并向图窗添加文本箭头。用归一化的图窗坐标指定文本箭头位置&#xff0c;起点为 (0.3,0.6)&#xff0c;终点为 (0.5,0.5)。通过设置 String 属性指定文本说明。 figure plot(1:10) x [0.3 0.5]; y [0.6 0.5]; annotation…

ClickHouse--08--SQL DDL 操作

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 SQL DDL 操作1 创建库2 查看数据库3 删除库4 创建表5 查看表6 查看表的定义7 查看表的字段8 删除表9 修改表9.1 添加列9.2 删除列9.3 清空列9.4 给列修改注释9.5 修…

C语言第二十四弹---指针(八)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 指针 1、数组和指针笔试题解析 1.1、字符数组 1.1.1、代码1&#xff1a; 1.1.2、代码2&#xff1a; 1.1.3、代码3&#xff1a; 1.1.4、代码4&#xff1a; 1…

thinkphp6入门(20)-- 如何上传图片、文件

1. 配置文件 设置上传的路径 对应文件夹 2. 前端 <div class"card-body"><h1 class"card-title">用户头像</h1><img src"../../../uploads/{$user.avatar_photo_path}" alt"avatar" height"100"/&g…

Windows 安装和连接使用 PgSql数据库

一. PostgreSQL 安装详细步骤 下载地址&#xff1a;https://www.enterprisedb.com/postgresql-tutorial-resources-training-1?uuidd732dc13-c15a-484b-b783-307823940a11&campaignIdProduct_Trial_PostgreSQL_16 1. 双击打开安装包 2. 选择安装目录 3. 选择安装组件 4.…

windows10系统转换成为window7s出现蓝屏错误ax000000A5

状况的描述&#xff1a; 由于电脑的基础性能有一些不匹配&#xff0c;想把windows10系统转换成为windows7的系统进行处理&#xff0c;利用widowspe的装机系统对其进行处理&#xff0c;但是对其进行相关的安装&#xff0c;目前在网络上搜索的相关文章分析的原因&#xff1a; 原…

蓝桥杯:C++排序

排序 排序和排列是算法题目常见的基本算法。几乎每次蓝桥杯软件类大赛都有题目会用到排序或排列。常见的排序算法如下。 第(3)种排序算法不是基于比较的&#xff0c;而是对数值按位划分&#xff0c;按照以空间换取时间的思路来排序。看起来它们的复杂度更好&#xff0c;但实际…

政安晨:梯度与导数~示例演绎《机器学习·神经网络》的高阶理解

这篇文章确实需要一定的数学基础&#xff0c;第一次接触的小伙伴可以先看一下我示例演绎这个主题的前两篇文章&#xff1a; 示例演绎机器学习中&#xff08;深度学习&#xff09;神经网络的数学基础——快速理解核心概念&#xff08;一&#xff09;&#xff1a; 政安晨&#…

蓝桥杯嵌入式学习记录——按键的使用

目录 一、按键原理简介 二、cubeMX的配置 三、按键的短按代码 四、按键的长按代码 一、按键原理简介 在STM32中&#xff0c;按键连接通常使用GPIO&#xff08;通用输入/输出&#xff09;端口来实现。当按键未被按下时&#xff0c;GPIO端口处于高电平状态&#xff08;即1&am…

springboot188基于spring boot的校园商铺管理系统

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

高德地图上绘制热力图的方法

百度地图和高德地图的JavaScript API都提供了热力图的绘制方法&#xff0c;都是将热力图作为新的图层&#xff0c;叠加到地图上。但是百度地图的经纬度体系与我们的经纬度存在偏差&#xff0c;高德的与我们相符&#xff0c;应当使用高德地图JavaScript API。 因为是JavaScript…

COM初体验——新建文档并写入内容。

我想在程序里和Word交互。老师跟我说不要学COM&#xff0c;因为它已经过时了。但是我不想再把代码移植到C#上面&#xff0c;然后用VSTO——已经用了std::unordered_set&#xff01;因为我使用了Copilot&#xff0c;结合我的思考&#xff0c;写了下面的代码&#xff1a; #impor…

【Langchain Agent研究】SalesGPT项目介绍(四)

【Langchain Agent研究】SalesGPT项目介绍&#xff08;三&#xff09;-CSDN博客 github地址&#xff1a;GitHub - jerry1900/SalesGPT: Context-aware AI Sales Agent to automate sales outreach. 上节课&#xff0c;我们主要介绍了SalesGPT的类属性和它最重要的类方法f…

【教学类-47-01】20240206UIBOT+IDM下载儿童古诗+修改文件名

背景需求&#xff1a; 去年12月&#xff0c;我去了其他幼儿园参观&#xff0c;这是一个传统文化德育教育特色的学校&#xff0c;在“古典集市”展示活动中&#xff0c;小班中班大班孩子共同现场念诵《元日》《静夜思》包含了演唱版本和儿歌念诵版本。 我马上也要当班主任了&a…

微信小程序开发学习笔记《17》uni-app框架-tabBar

微信小程序开发学习笔记《17》uni-app框架-tabBar 博主正在学习微信小程序开发&#xff0c;希望记录自己学习过程同时与广大网友共同学习讨论。建议仔细阅读uni-app对应官方文档 一、创建tabBar分支 运行如下的命令&#xff0c;基于master分支在本地创建tabBar子分支&#x…