当前位置: 首页 > news >正文

排序方法——堆排序

文章目录

  • 一、堆的概念
  • 二、向下调整法
  • 三、堆排序
    • 建堆
    • 排序
  • 四、 完整代码

一、堆的概念


  堆的概念:一个按照完全二叉树的储存方式存储的一维数组我们称之为堆。


  堆可以分为大堆和小堆:
  大堆:二叉树中父亲节点的值都比自己的孩子节点的值大;
  小堆:二叉树中父亲节点的值都比自己的孩子节点的值小;
在这里插入图片描述
  这就是很明显的一组大小堆。
  堆排序的实现就是在对的基础上完成的。

二、向下调整法

  实现堆排序,用向下调整法时间复杂度最低
下面是向下调整的代码:

void Swap(int* x, int* y)
{int ret = *x;*x = *y;*y = ret;
}//降序建小堆
//升序建大堆
void AdjustDown(int* arr, int n, int father)
{                 // arr为数组 n为数组元素个数  father为当前数组下标//假设左孩子大int child = 2 * father + 1;while (child < n)//结束条件为到达了最后一层,最后一层没有孩子{//比较左右孩子,找出最大的孩子//if (child + 1 < n && arr[child + 1] < arr[child])//小堆, 降序if (child + 1 < n && arr[child + 1] > arr[child])//大堆, 升序{   //child+1<n是为了防止数组越界,    child++; //如果右孩子大于(小于)左孩子,child就加1}//if (arr[father] > arr[child])//小堆, 降序if (arr[father] < arr[child])//大堆, 升序 {Swap(&arr[father], &arr[child]);//father的值小于child的值,让二者交换father = child;  //再次进行下一组的交换,重新定义father和childchild = 2 * father + 1;}else{break;}}}

  以上就是向下调整法建大/小堆的过程。

三、堆排序

  建好堆以后就开始进行排序了,即将此时堆里的数值从上向下梳理一遍,使其变的有序。

  后面我们以大堆排升序为例进行讲解。

建堆

自定义一个函数HeapSort,用来进行堆排序

void HeapSort(int* arr, int n)
{//向下调整建堆for (int i = (n - 1 - 1) / 2; i >= 0; i--) //(n - 1 - 1) / 2是最后一个有孩子的父节点{AdjustDown(arr, n, i);}
}

  假设有一个数组:arr[ ] = {2, 8, 9, 4, 7, 5, 6, 1, 3, 10}
在这里插入图片描述
  接下来,根据代码对数组元素进行比较:从以数字7为父节点开始进行调整
在这里插入图片描述
以上是向上调整建堆的全过程,最终得到数组arr[ ] = {10, 8, 9, 4, 7, 5, 6, 1, 3, 2}。
在这里插入图片描述

排序

  建完堆就该排序了

void HeapSort(int* arr, int n)
{//向下调整建堆for (int i = (n - 1 - 1) / 2; i >= 0; i--){AdjustDown(arr, n, i);}int end = n - 1;while (end > 0){Swap(&arr[0], &arr[end]);AdjustDown(arr, end, 0);end--;}
}

  变量end代表数组最后一个元素下标,排序需要遍历数组,所以end也可做完while循环的判断条件。
  这里将arr[0]与arr[end]交换,再进行向下调整,遍历整个数组,结束后数组变为有序数组,堆排序也就完成了。


  首先,将2和10进行交换
在这里插入图片描述
  从上向下依次进行比较,较大的数往下走,较小的数往上走。
在这里插入图片描述

以上是一次循环的过程,后面的循环同理,最后就会的到一组有序的数组。
在这里插入图片描述
  每一次循环结束后,end–, 继续将arr[0]与arr[end]交换,继续进行同样的排序。

在这里插入图片描述

四、 完整代码

//堆排序
//降序建小堆
//升序建大堆
void Swap(int* x, int* y)
{int ret = *x;*x = *y;*y = ret;
}void AdjustUp(int* arr, int child)
{int father = (child - 1) / 2;//while (child > 0)while(father >= 0){if (arr[father] < arr[child])//大堆  升序//if (arr[father] > arr[child])//小堆  降序{Swap(&arr[father], &arr[child]);child = father;father = (child - 1) / 2;}else{break;}}
}void AdjustDown(int* arr, int n, int father)
{//假设左大int child = 2 * father + 1;while (child < n){//找出最大的孩子//if (child + 1 < n && arr[child + 1] < arr[child])//小堆, 降序if (child + 1 < n && arr[child + 1] > arr[child])//大堆, 升序{child++;}//if (arr[father] > arr[child])//小堆, 降序if (arr[father] < arr[child])//大堆, 升序{Swap(&arr[father], &arr[child]);father = child;child = 2 * father + 1;}else{break;}}}void HeapSort(int* arr, int n)
{//向下调整建堆for (int i = (n - 1 - 1) / 2; i >= 0; i--){AdjustDown(arr, n, i);}//向上调整建堆/*for (int i = 1; i < n; i++){AdjustUp(arr, i);}*/int end = n - 1;while (end > 0){Swap(&arr[0], &arr[end]);AdjustDown(arr, end, 0);end--;}
}int main()
{int arr[] = { 2,8,9,4,7,5,6,1,3,10 };int sz = sizeof(arr) / sizeof(arr[0]);HeapSort(arr, sz);for (int i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;
}

相关文章:

  • Qt实现窗口失去焦点抖动功能
  • 在 Kubesphere 中开启新一代云原生数仓 Databend
  • 基于51单片机的超声波测距—数码管显示
  • sqliteSQL基础
  • 理解lambda表达式
  • 在本地电脑中如何用命令操作远程服务器上的数据库
  • [力扣题解] 28. 找出字符串中第一个匹配项的下标
  • 【算法】模拟算法——Z字形变换(medium)
  • Python魔法之旅-魔法方法(08)
  • BearPi-HM Nano开发笔记
  • LiveWeb前端:深度解析与挑战应对
  • net语言编程:深入探索其奥秘与挑战
  • 说说影响网络的因素
  • Java网络编程(上)
  • 【Linux】如何利用linux项目自动化构建工具-make/Makefile以及vim编辑器构建两个小程序:倒计时和进度条
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • @angular/forms 源码解析之双向绑定
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • Android开发 - 掌握ConstraintLayout(四)创建基本约束
  • canvas 五子棋游戏
  • Laravel Mix运行时关于es2015报错解决方案
  • Mithril.js 入门介绍
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • python3 使用 asyncio 代替线程
  • Stream流与Lambda表达式(三) 静态工厂类Collectors
  • 从重复到重用
  • 给github项目添加CI badge
  • 技术发展面试
  • 开源地图数据可视化库——mapnik
  • 老板让我十分钟上手nx-admin
  • 如何胜任知名企业的商业数据分析师?
  • 微服务入门【系列视频课程】
  • 与 ConTeXt MkIV 官方文档的接驳
  • 在weex里面使用chart图表
  • 3月27日云栖精选夜读 | 从 “城市大脑”实践,瞭望未来城市源起 ...
  • 400多位云计算专家和开发者,加入了同一个组织 ...
  • 通过调用文摘列表API获取文摘
  • 完善智慧办公建设,小熊U租获京东数千万元A+轮融资 ...
  • ​configparser --- 配置文件解析器​
  • ​软考-高级-信息系统项目管理师教程 第四版【第19章-配置与变更管理-思维导图】​
  • # Kafka_深入探秘者(2):kafka 生产者
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • #《AI中文版》V3 第 1 章 概述
  • #pragma pack(1)
  • #QT(串口助手-界面)
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • (13)Hive调优——动态分区导致的小文件问题
  • (CVPRW,2024)可学习的提示:遥感领域小样本语义分割
  • (pytorch进阶之路)扩散概率模型
  • (TipsTricks)用客户端模板精简JavaScript代码
  • (ZT) 理解系统底层的概念是多么重要(by趋势科技邹飞)
  • (篇九)MySQL常用内置函数
  • (学习日记)2024.03.12:UCOSIII第十四节:时基列表
  • (一)Mocha源码阅读: 项目结构及命令行启动
  • (原創) 物件導向與老子思想 (OO)