C/C++ 堆排序

个人主页:仍有未知等待探索-CSDN博客

专题分栏:数据结构_仍有未知等待探索的博客-CSDN博客

                                                      欢迎大家来指教!

一、前言

今天要介绍的是堆排序。

首先什么是堆?简而言之,堆就是二叉树的数组形式,用数组来存储二叉树。

这个堆和C语言中讲的堆区是不同的两个概念,不要混淆。

二、堆排序

堆排序的核心就是构建一个特殊的二叉树,这个二叉树的特性是:其父节点大于等于(小于等于)其左右孩子结点。

故,最终创建的二叉树的根节点会是该二叉树的最大值(最小值)。

那怎么才能让整个数组中的数据有序呢?那我们就让数组中第一个数和最后一个数进行交换,然后以第一个数和倒数第二个数为端点,继续进行构建堆,然后选出次最小值。以此类推~~~

我以大根堆为例(从数组下标为1的地方开始存储):

1、堆的数据类型

typedef int HpDataType;
typedef struct Heap
{HpDataType* a;//进行存储堆中的数据int size;//该堆的有效数据个数int capacity;//该堆中的容量
}Hp;

2、堆的初始化

//初始化
void Heapinit(Hp* php)
{assert(php);//断言,如果php为空的话,报错php -> a = NULL;php -> size = 0;php -> capacity = 0;
}

3、堆的销毁

//堆的销毁
void HeapDestory(Hp* php)
{assert(php);free(php -> a);//释放掉开辟的空间php -> a = NULL;//防止php -> a为野指针php -> size = 0;php -> capacity = 0;
}

4、堆的创建

// 堆的创建
// k为要插入到堆里面的元素
void Heap_push(Hp* php, int k)
{assert(php); //断言if (php -> size == php -> capacity)// 如果容量不够,扩容{// 如果容量为0,则给个初始值,否则就二倍扩容int size = php -> capacity == 0 ? 4 : php -> capacity * 2;Hp* tmp = (Hp* ) realloc(php -> a, (size + 1) * sizeof(int));if (tmp == NULL) {perror("realloc failed");exit(-1);// 扩容失败则结束程序}php -> a = tmp;php -> capacity = size;	}// 插入到堆的最后php -> a[++ php -> size] = k;// 向上调整,如果比父节点要大就进行交换up(php -> a, php -> size);
}

 5、向上调整

// 向上调整
// idx为要调整元素的下标
void up(int* a, int idx)
{assert(a);int child = idx;// 该结点下标int parent = child / 2;// 该结点的父节点,我是从下标为1开始存的while (child != 1){if (a[parent] < a[child]){Swap(&a[parent], &a[child]);}else{// 不需要调整,就退出break;}// 继续向上找child = child / 2;parent = parent / 2;}
}

 6、删除堆的最后一个元素

该操作的主要作用是将该堆中最大的元素进行归位,并且进行调整除了最后一个元素的二叉树的顺序,使其仍为一个堆。

// 进行删除最后一个元素
void Heappop(Hp* php)
{assert(php);assert(php -> size > 0);Swap(&php -> a[1], &php -> a[php -> size]);php -> size --;int parent = 1;int child = 2 * parent;while (child <= php -> size){// 假设左节点最大,如果右结点比左节点大,就child存右节点下标if (child + 1 <= php -> size && php -> a[child + 1] > php -> a[child]){child += 1;}// 判断孩子结点和父节点的值if (php -> a[parent] < php -> a[child]){Swap(&php -> a[parent], &php -> a[child]);}else {// 不需要则退出break;}parent = child;child = 2 * parent;}
}

 7、取出堆顶元素

// 取出堆顶元素
HpDataType Heaptop(Hp* php)
{assert(php);assert(php -> size > 0);return php -> a[1];
}

三、总代码及其运行结果

#define _CRT_SECURE_NO_WARNINGS  1// 大根堆#include <stdio.h>
#include <assert.h>
#include <stdlib.h>typedef int HpDataType;
typedef struct Heap
{HpDataType* a;// 进行存储堆中的数据int size;// 该堆的有效数据个数int capacity;// 该堆中的容量
}Hp;void Heapinit(Hp* php);// 初始化
void HeapDestory(Hp* php);// 堆的销毁
void Heap_push(Hp* php, int k);// 堆的创建
void Swap(int* a, int* b);// 交换
void up(int* a, int idx);// 向上调整
HpDataType Heaptop(Hp* php);// 取堆顶元素
void Heappop(Hp* php);// 删除堆的最后一个元素int main()
{int a[] = {1, 2, 3, 4, 5, 6, 7};Hp hp;Heapinit(&hp);int len = sizeof(a) / sizeof(a[0]);for (int i = 0; i < len; i++ ){Heap_push(&hp, a[i]);}printf("初始堆:\n");for (int i = 1; i <= len; i ++ ){printf("%d ", hp.a[i]);}printf("\n有序序列:\n");while (hp.size > 0){printf("%d ", Heaptop(&hp));Heappop(&hp);}HeapDestory(&hp);return 0;
}// 初始化
void Heapinit(Hp* php)
{assert(php);// 断言,如果php为空的话,报错php -> a = NULL;php -> size = 0;php -> capacity = 0;
}// 堆的销毁
void HeapDestory(Hp* php)
{assert(php);free(php -> a);// 释放掉开辟的空间php -> a = NULL;// 防止php -> a为野指针php -> size = 0;php -> capacity = 0;
}void Swap(int* a, int* b)
{int tmp = *a;*a = *b;*b = tmp;
}// 向上调整
// idx为要调整元素的下标
void up(int* a, int idx)
{assert(a);int child = idx;// 该结点下标int parent = child / 2;// 该结点的父节点,我是从下标为1开始存的while (child != 1){if (a[parent] < a[child]){Swap(&a[parent], &a[child]);}else{// 不需要调整,就退出break;}// 继续向上找child = child / 2;parent = parent / 2;}
}// 堆的创建
// k为要插入到堆里面的元素
void Heap_push(Hp* php, int k)
{assert(php); //断言if (php -> size == php -> capacity)// 如果容量不够,扩容{// 如果容量为0,则给个初始值,否则就二倍扩容int size = php -> capacity == 0 ? 4 : php -> capacity * 2;Hp* tmp = (Hp* ) realloc(php -> a, (size + 1) * sizeof(int));if (tmp == NULL) {perror("realloc failed");exit(-1);// 扩容失败则结束程序}php -> a = tmp;php -> capacity = size;	}// 插入到堆的最后php -> a[++ php -> size] = k;// 向上调整,如果比父节点要大就进行交换up(php -> a, php -> size);
}// 取出堆顶元素
HpDataType Heaptop(Hp* php)
{assert(php);assert(php -> size > 0);return php -> a[1];
}// 进行删除最后一个元素
void Heappop(Hp* php)
{assert(php);assert(php -> size > 0);Swap(&php -> a[1], &php -> a[php -> size]);php -> size --;int parent = 1;int child = 2 * parent;while (child <= php -> size){// 假设左节点最大,如果右结点比左节点大,就child存右节点下标if (child + 1 <= php -> size && php -> a[child + 1] > php -> a[child]){child += 1;}// 判断孩子结点和父节点的值if (php -> a[parent] < php -> a[child]){Swap(&php -> a[parent], &php -> a[child]);}else {// 不需要则退出break;}parent = child;child = 2 * parent;}
}

 

谢谢大家! 

 

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

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

相关文章

css3边框与圆角

css3边框与圆角 前言边框的三要素边框的三要素小属性 四个方向的边框四个方向边框的三要素小属性 去掉边框利用边框制作三角形圆角 border-radius单独设置四个圆角小属性百分比为单位 盒子阴影阴影延展内阴影多阴影 结语 前言 在网页设计中&#xff0c;边框与圆角不仅仅是简单…

邂逅Node.JS的那一夜

邂逅Node.JS的那一夜&#x1f303; 本篇文章&#xff0c;学习记录于&#xff1a;尚硅谷&#x1f3a2; 本篇文章&#xff0c;并不完全适合小白&#xff0c;需要有一定的HTML、CSS、JS、HTTP、Web等知识及基础学习&#xff1a; &#x1f197;&#xff0c;紧接上文&#xff0c;…

uⅤ打印-小理光上海RYPC后台运动系统

uⅤ打印-小理光上海RYPC后台运动系统

ISO 11519-2 开环低速 CAN 网络(10K~125Kbps)

ISO 11519-2 标准的物理框图如下图 可理解为一个低速开环 CAN 总线网络&#xff1b;CAN 开环总线网络允许总线最大长度为 1km;最高速度为 125Kbps;这里的两根线是独立的&#xff0c;每根线上串联一个 2.2kΩ 的电阻&#xff1b;节点就是不同的设备&#xff0c;连接到一个开环总…

【微服务】日志搜集es+kibana+filebeat+redis+logstash(单机)

日志搜集系统搭建 基于7.17.16版本 ps: 项目是toB的&#xff0c;日志量不大 前置准备 软件下载 7.17.16版本。8.x版本需要JDK11 elastic.co/downloads/past-releasesJDK java8 Linux elastic 软件不能以root用户启动&#xff0c;需要创建用户 sudo useradd elastic #给此…

解决:ModuleNotFoundError: No module named ‘pymysql’

解决&#xff1a;ModuleNotFoundError: No module named ‘pymysql’ 文章目录 解决&#xff1a;ModuleNotFoundError: No module named pymysql背景报错问题报错翻译报错位置代码报错原因解决方法方法一&#xff0c;直接安装方法二&#xff0c;手动下载安装方法三&#xff0c;…

云贝教育 |【技术文章】存储对象的LIBRARY CACHE LOCK/PIN实验(一)

注: 本文为云贝教育 刘峰 原创&#xff0c;请尊重知识产权&#xff0c;转发请注明出处&#xff0c;不接受任何抄袭、演绎和未经注明出处的转载。 实验环境 操作系统&#xff1a;Red Hat Enterprise Linux release 8.8 (Ootpa) 数据库&#xff1a;oracle Version 19.3.0.0.0 …

UE 引擎工具笔记

2023虚幻技术分享会视频 1.2023年虚幻引擎最新功能和技巧 [UFSH2023]2023年虚幻引擎最新功能和技巧 | Chris Murphy Epic Games_哔哩哔哩_bilibili 推荐细看下.总结了UE5的功能大概 2.调试技巧 [UFSH2023]总有一个你不知道的虚幻引擎调试技巧 | 陈拓 Epic Games_哔哩哔哩_…

深信服态势感知一体机SIP-1000 Y2100 3.0.1Y升级3.0.3Y步骤

当前版本&#xff1a;3.0.1Y 升级后版本&#xff1a;3.0.3Y PS&#xff1a;3.0.1Y不能直升3.0.3Y&#xff0c;需要先通过升级工具升级到3.0.2Y&#xff0c;再安装前置补丁从3.0.2Y升级到3.0.3Y&#xff1b;每一次升级时间为20-30分钟&#xff0c;设备升级会重启&#xff0c;需提…

计算机网络-VLAN间通信

之前复习了VLAN的概念以及几个接口类型。VLAN在二层可以实现广播域的划分&#xff0c;VLAN间可以实现二层通信&#xff0c;但是不能实现三层通信&#xff0c;需要借助其它方式。 一、概述 实际网络部署中一般会将不同IP地址段划分到不同的VLAN。同VLAN且同网段的PC之间可直接进…

2023 Gartner® 云数据库管理系统魔力象限发布 PingCAP 入选“荣誉提及”

近日&#xff0c;全球 IT 市场研究和咨询 公司 Gartner 发布最新报告《Magic Quadrant™ for Cloud Database Management Systems》&#xff08;云数据库管理系统魔力象限&#xff09;&#xff0c; 企业级开源分布式数据库厂商 PingCAP 入选“荣誉提及” 。前不久&#xff0c;P…

GENMARK控制器维修SMALL SMC4092

晶圆转移机器人SMALL CONTROLLER控制器维修 SMC1100 半导体设备机械臂GENMARK控制器维修 eSensor特点&#xff1a; &#xff08;1&#xff09;基于DNA杂交和电化学检测原理&#xff1b; &#xff08;2&#xff09;电化学传感检测&#xff0c;并非荧光或光学检测。 电子信号的…

查准率与查全率在自然语言处理中的核心概念与联系、核心概念和实践应用,如何使用朴素贝叶斯、SVM 和深度学习实现查准率和查全率的计算?

查准率与查全率在自然语言处理中的核心概念与联系、核心概念和实践应用,如何使用朴素贝叶斯、SVM 和深度学习实现查准率和查全率的计算? 人工智能核心技术有:1. 深度学习;2.计算机视觉;3.自然语言处理;4.数据挖掘。其中,深度学习就是使用算法分析数据,从中学习并自动归…

【Oracle】数据库查询与SQL语句

Oracle查询 一、单表查询 1、简单条件查询 1&#xff09;精确查询 SELECT* FROMT_OWNERS WHEREwatermeter 304082&#xff09;模糊查询 SELECT* FROMt_owners WHEREname LIKE %刘%3&#xff09;and运算符 SELECT* FROMt_owners WHEREname LIKE %刘% AND housenumb…

HTML--文本

文本一般存在于 body下 段落标签&#xff1a;<p> </p> 换行标签&#xff1a;<br/> 放在一句话里可以换行 <p>这是一段话<br/>这是另一段话</p>文本标签分以下几种&#xff1a; 粗体标签&#xff1a;strong&#xff0c;b 斜体标签&#xf…

VUE+bpmn.js实现工作流

1、安装bpmn.js npm install bpmn-js7.3.1 // 我安装的版本是7.3.1npm install bpmn-js-properties-panel0.37.2npm install bpmn-moddle7.1.3 npm install --save camunda-bpmn-moddle 2、配置axios&#xff0c;在main.js中引入axios import axios from axiosVue.proto…

小汪,TCP连接和断连夺命6连问你可能扛得住?

目录 TCP三次握手连接和四次挥手断连的几处疑问 一、建立连接&#xff0c;为什么是三次握手&#xff0c;而不是二次握手&#xff1f; 二、为什么每次建立 TCP 连接时&#xff0c;初始化的序列号都要求不一样呢&#xff1f; 三、断开连接&#xff0c;为什么是四次握手&#x…

机器学习激活函数

激活函数 激活函数是人工神经网络中的一个重要组成部分。它们用于向神经网络中添加非线性因素&#xff0c;使得网络能够解决复杂问题&#xff0c;如图像识别、语言处理等。激活函数的作用是决定一个神经元是否应该被激活&#xff0c;也就是说&#xff0c;它帮助决定神经元的输…

科技顶天,市场立地 。璞华科技“顶天立地”的成长之路

科技顶天&#xff0c;市场立地。 几十年来&#xff0c;我们越来越深刻地认识到&#xff0c;这就是真理&#xff0c;质朴而深刻。尤其在当前特殊的国际国内商业环境中&#xff0c;这一理念不但没有过时&#xff0c;反而恰逢其时。有这么一家企业&#xff0c;一直践行“科技顶天…

使用阿里云镜像创建一个Spring Boot项目

由于现在的idea在创建项目时已经不支持Java8版本了&#xff0c;如果我们还想用8版本&#xff0c;可以使用阿里云镜像创建。所以得改变原有的地址为&#xff1a;https://start.aliyun.com springboot版本选择2开头的任意版本的。 1.配置6个依赖 2.改变下载依赖地址 下载依赖默认…