八大排序算法——堆排序

堆排序算法(图解详细流程) 提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录堆排序基本介绍大顶堆举例说明小顶堆举例说明堆排序的基本思想堆排序步骤图解说明堆排序的基本思路总结 堆排序基本介绍 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏最好,平均时间复杂度均为O(nlogn),他也是不稳定排序 堆是具有以下性质的完全二叉树,每个节点的值都大于或等于其左右孩子节点的值,称为大顶堆,注意:没有要求节点的左孩子的值和右孩子的值的大小关系。 每个结点的值都小于或等于其左 阅读详情
AI摘要

本文详细介绍了堆排序算法的工作原理,包括如何构建大根堆并利用其特性进行排序。通过具体的实例展示了堆排序的具体步骤,并提供了完整的C语言实现代码。

八大排序

排序,分为内部排序和外部排序,内部排序是指将数据记录在内存中进行排序,而外部排序因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存,所以称之为外部排序,我们这里讲的八大排序全部属于内部排序。

这里写图片描述

八大排序时间/空间复杂度及稳定性

这里写图片描述

堆排序

堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。可以利用数组的特点快速定位指定索引的元素。堆分为大根堆和小根堆,是完全二叉树。大根堆的要求是每个节点的值都不大于其父节点的值,即A[PARENT[i]] >= A[i]。在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶。这里要注意的是堆排序采用的是完全二叉树的思想,但它的存储结构采用的是数组。

堆排序的过程(大根堆)
  • 调整堆:调整堆即是将最初无规则的堆调整为大根堆。它的每一次调整都是将非叶子结点i与其左孩子left[i]和右孩子light[i]进行比较,若非叶子结点i不是其中最大的,那么将其与最大的结点位置互换。堆的第一次调整是从最后一个非叶子结点开始依次向根节点调整的,这就是为什么它要采用完全二叉树的原因,因为这样可以快速的在数组中定位最后一个非叶子结点,即a[n/2-1],其中a是待排序的数组,n是数组a的下标值。那么就是说,下标为n/2-1的结点就是最后一个非叶子节点。堆的第一次调整函数的调用关系大概可以总结为循环调用+递归调用。其过程如下:
    • 初始完全二叉树
      初始完全二叉树
    • 数值3为最后一个非叶子结点,将其与它的孩子结点相比较,8>3,位置互换
      这里写图片描述
    • 判断被调整后的结点3是否为非叶子结点,3不是,函数调用进入下一层循环,将结点7与它的左右儿子结点相比较,20>17>7,将结点20与结点7位置互换
      这里写图片描述
    • 判断被调整后的结点7是否为非叶子结点,7不是,函数调用进入最后一层循环,将结点16与它的左右儿子结点相比较,20>16>7,将结点16与结点20位置互换
      这里写图片描述
    • 判断被调整后的结点16是否为非叶子结点,16是,函数进行递归调用,将结点16与它的左右儿子结点相比较,17>16>7,将结点17与结点16位置互换
      这里写图片描述
    • 判断被调整后的结点16是否为非叶子结点,16不是,循环结束,堆调整完毕。
  • 堆排序:可以看到,上面的调整堆算法循环调用执行完毕以后,结果是一个大根堆,堆排序所要做的就是将堆顶元素20与最后一个元素3互换位置,即将a[0]与a[n-1]互换位置,换位置之后a[0]至a[n-2]元素又组成一个新的堆,这时的调整堆与第一次调整刚好相反,它是从堆顶元素开始调整,一直往下延伸,是一个纯递归的过程,具体过程如下:
    这里写图片描述这里写图片描述这里写图片描述这里写图片描述这里写图片描述这里写图片描述这里写图片描述这里写图片描述这里写图片描述这里写图片描述这里写图片描述
    到这里,排序就算是执行完了,从上述过程可知,堆排序其实也是一种选择排序,是一种树形选择排序。只不过直接选择排序中,为了从a[1…n]中选择最大记录,需比较n-1次,然后从a[1…n-2]中选择最大记录需比较n-2次。事实上这n-2次比较中有很多已经在前面的n-1次比较中已经做过,而树形选择排序恰好利用树形的特点保存了部分前面的比较结果,因此可以减少比较次数,这就是为什么第一次调整堆是从下往上,而之后都是从上往下。对于n个关键字序列,最坏情况下每个节点需比较log2(n)次,因此其最坏情况下时间复杂度为nlogn。堆排序为不稳定排序,不适合记录较少的排序。下面是堆排序的c语言实现:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>

//堆调整算法
void HeapAdjust(int num[],int i,int length)
{
    //定义max保存以num[i]为根的最小堆中最大值的下标,初始值为i
    int max=i;
    //判断num[i]是否为根结点 (下标i<=length/2-1的结点都是根节点)
    if(i<=length/2-1)
    {
        //判断num[2*i+1]是否在堆内,若在,判断其是否大于num[max],若大于,将其下标2*i+1赋予给max
        if((2*i+1)<length && num[2*i+1]>num[max])
        {
            max=2*i+1;
        }
        //判断num[2*(i+1)]是否在堆内,若在,判断其是否大于num[max],若大于,将其下标2*(i+1)赋予给max
        if((2*(i+1))<length && num[2*(i+1)]>num[max])
        {
            max=2*(i+1);
        }
        //若i不等于max,则说明以num[i]为根的最小堆中num[max]是最大值,将num[max]与根结点num[i]交换位置
        if(i!=max)
        {
            num[i]=num[i]^num[max];
            num[max]=num[i]^num[max];
            num[i]=num[i]^num[max];
            //交换后,为防止以num[max]为根结点的最小堆结构发生变换,再次调用堆调整算法
            HeapAdjust(num,max,length);
        }
    }
}
//堆排序算法
void HeapSort(int num[],int length)
{
    int i;
    //找到最后一个非叶子结点,先从最后一个非叶子结点组成的最小堆进行堆调整
    for(i=length/2-1;i>=0;i--)
        //调用调整堆算法将数组从下往上调整为大根堆
        HeapAdjust(num,i,length);
    for(i=length-1;i>0;i--)
    {
        //将数组第一个数和最后一个数换位置
        num[i]=num[i]^num[0];
        num[0]=num[i]^num[0];
        num[i]=num[i]^num[0];
        //继续调用调整堆算法,将剩余数据组成的堆从上往下调整为大根堆
        HeapAdjust(num,0,i);
    }
}
int main()
{
    int i;
    int num[]={8,5,7,12,48,36,4};
    HeapSort(num,sizeof(num)/sizeof(int));
    for(i=0;i<sizeof(num)/sizeof(int);i++)
    {
        printf("%d\t",num[i]);
    }
    printf("\n");
}

堆排序的基本概念和基本思路 一 堆排序基本介绍 1 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序, 它的最坏、最好、平均时间复杂度均为 O(nlogn), 它也是不稳定排序。 2 堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,这种情况称为大顶堆,注意:没有要求结点的左孩子的值和右孩子的值的大小关系。 3 每个结点的值都小于或等于其左右孩子结点的值,这种情况称为小顶堆。 4 大顶堆举例说明 5 小顶堆举例说明 6 一般升序采用大顶堆, 降序采用小顶堆。 二 堆.. 阅读详情

相关推荐

堆排序详细图解(通俗易懂)

什么是堆 堆是一种叫做完全二叉树的数据结构,可以分为大根堆,小根堆,而堆排序就是基于这种结构而产生的一种程序算法。 堆的分类 大根堆:每个节点的值都大于或者等于他的左右孩子节点的值 小根堆:每个结点的值都小于或等于其左孩子和右孩子结点的值 两种结构映射到数组为: 大根堆: 小根堆: //父-->子:i--->左孩子:2*i+1, 右孩子:2*i+2; //子-->父:i--->(i-1)*2;(i为下标元素) 排序思想 1.首先将待排序的数...

oorik的博客 32万+

十大经典排序算法----堆排序(超详细)

堆排序,超详细,C语言版

m0_73096566的博客 2万+

Camera AF和FF

Camera按对焦功能可以分为FF(Fixed Focus)和AF(Auto Focus),即固定对焦和自动对焦。固定对焦顾名思义就是焦距是固定的,而自动对焦可以通过移动镜头位置来改变焦距从而实现自动对焦。以前摄像的功能机大多是固定对焦,现在的手机都带有自动对焦功能。 FF模组包括镜头(Lens),传感器(Sensor),红外滤色器(IR Filter),电路板(PCB),镜头支撑(Lens Holder),连接器(Connector)。 Fig 1. FF Module AF模组包括FF模组,音圈马达(V

Coppa的博客 1万+

堆排序详解(Heap Sort)

构造的过程就是将无序的序列构造成一个堆的过程。堆的定义是:对于任意一个非叶子节点 i,其左子节点为 2i+1,右子节点为 2i+2,且父节点的值大于等于(或小于等于)其子节点的值。因此,我们可以从最后一个非叶子节点开始,依次将其与其子节点比较,如果不满足堆的定义,则交换位置,直到整个序列构造成一个堆为止。排序的过程就是将堆顶元素与最后一个元素交换位置,然后将剩余元素重新构造成一个堆的过程。每次交换后,堆的大小减一,因此我们可以通过一个变量来记录堆的大小,从而将排序的过程限制在堆的范围内。

Wzill 5663

【LLM】ms-Swift框架下SFT与GRPO协同优化的高效训练策略

本文深入探讨了ms-Swift框架下监督微调(SFT)与群组相对策略优化(GRPO)的协同训练策略,提升大型语言模型(LLM)的性能与效率。通过创新的架构设计和两阶段训练流程,结合GRPO的群组奖励估计与动态基线调整技术,显著优化了数学推理等任务的准确率。文章还分享了计算资源高效利用和参数调优的实战经验,为LLM训练提供了实用指导。

green的博客 994

WRF和WPS模型在Ubuntu系统上的安装与常见问题解决指南

本文详细介绍了在Ubuntu系统上安装WRF和WPS模型的完整教程,涵盖系统环境配置、依赖库安装、源代码编译以及常见问题的解决方案。重点解决了WPS编译中intmath.f文件的修改、环境变量设置和编译器兼容性等关键难点,帮助用户高效部署气象研究与预报模型。

weixin_29213525的博客 382

八大排序算法---堆排序

这是一个大顶堆,每个父节点都比孩子大。 package suanfa; import java.util.Arrays; public class Duipaixu { //维护大顶堆 static void dadingdui(int[] arr,int n,int i) { int largest = i;//父节点i int lson = 2*i+1;//左孩子 int rson = 2*i+2;//右孩子 //如果哪个孩子的值大于父节点则把最大值的下标给到lar...

weixin_57711380的博客 758

基于R语言 meta/metafor 包进行荟萃分析(一)

在此部分中,使用连续结果详细描述了通用逆方差方法及其在meta分析中的应用,还介绍了固定效应法和随机效应法。我们已经展示了如何分别将典型数据与metacont和metagen函数一起使用,以及如何print和绘制森林图。我们还讨论了估计研究间方差的各种方法,并将Hartung-Knapp平差描述为经典随机效应方法的替代方法。此外,我们还说明了byvar选项的使用,这使得亚组分析更加简单。关于亚组分析的更多细节见后续章节。

Dunaichuanyi的博客 1万+

八大排序算法--堆排序

参考文章链接:https://www.cnblogs.com/skywang12345/p/3602162.html 原理: 指利用堆这种数据结构所设计的一种排序算法。 初始化堆:将数列a[1...n]构造成大(小)顶堆。 交换数据:将a[1]和a[n]交换,使a[n]是a[1...n]中的最大(小)值;然后将a[1...n-1]重新调整为大(小)顶堆。 接着,将a[1]和a[n-1]交换,使a[n-1]是a[1...n-1]中的最大(小)值;然后将a[1...n-2]重新调整为大(小)顶堆。 .

xyq_mxnx的博客 187

q-learning精讲

Q-learning Q-learning是一种用于机器学习的强化学习技术。 Q-learning的目标是学习一种策略,告诉Agent在什么情况下要采取什么行动。 它不需要环境模型,可以处理随机转换和奖励的问题,而无需进行调整。 对于任何有限马尔可夫决策过程(FMDP),Q学习找到一种最优的策略,即从当前状态开始,它在任何和所有后续步骤中最大化总奖励的预期值。在给定无限探索时间和部分随机策略的情况...

weixin_41697507的博客 1万+

阿波罗开发板硬件架构与STM32模块化设计详解

嵌入式开发板的模块化设计是提升硬件复用性、降低迭代成本的关键技术路径。其核心在于底板与核心板的电气解耦与功能分层,依托STM32系列MCU(如F429/F767)的丰富外设资源与引脚复用能力,实现信号完整性、电源域隔离与热管理的系统级协同。该架构显著支撑工业HMI、智能家居网关、便携医疗设备等典型场景,尤其在RGB LCD驱动、QSPI Flash内存映射、多协议通信(CAN/RS485/USB)及低功耗唤醒(WK_UP按键)等工程实践中展现出高可靠性与易调试性。本文围绕阿波罗开发板展开深度解析,覆盖最小系

weixin_42510201的博客 64

八大排序算法之堆排序

JAVA实现堆排序 堆排序 利用:顺序结构的二叉树 原理:借用大顶堆和小顶堆 堆的分类 1.大顶堆(大根堆):父节点的值大于任意一个子节点 2.小顶堆(小根堆):父节点的值小于任意一个子节点 步骤: 1.构造一个大顶堆,取堆顶数字(最大值) 2.剩下的数字再构造一个大顶堆,取堆顶数字(剩余数中的最大值) 3.重复以上操作,直到取完堆中的数字 图片示例: 代码: //堆排序 public static void heapSort(int[] arr) { /* 开始位置是最后一个元素的父节点

qq_42412309的博客 215

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的生活垃圾检测与分类系统(Python+PySide6界面+训练代码)

随着城市化进程的加速和人口增长,生活垃圾管理已成为现代城市面临的重要挑战。传统的垃圾处理方法效率低下且成本高昂,急需智能化解决方案。本文详细介绍了基于YOLO系列算法(特别是YOLOv8)的智能生活垃圾检测与分类系统,该系统能够实时识别和分类多种生活垃圾,为智能垃圾处理和回收提供技术支持。系统包含完整的数据集构建、模型训练、评估和可视化界面,并提供了完整的实现代码。

YOLO 117

C语言八大排序算法性能实测:10万数据下快排与堆排序耗时对比

本文通过实测对比C语言中八大经典排序算法在10万随机整数排序场景下的性能表现,重点分析快速排序与堆排序的耗时差异。测试结果显示,快速排序平均耗时仅0.016秒,表现最优;堆排序紧随其后,耗时0.022秒。文章详细解析了各排序算法的实现原理、时间复杂度及适用场景,为开发者提供了实用的排序算法选择指南。

csxc65837的博客 419

软考高级-系统架构设计师 知识点整理 (一篇就够了 建议收藏)

软考高级-系统架构设计师知识点整理---十万字总结,助你通过高级

片言可决讼,半纸能缚龙 7348

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

八大排序算法 之 堆排序

例如数组 a={19,3,60,7,1,15,33,24,45,32,79,85};排序思想:1,堆排序也是选择排序的一种,根据堆得特性,每次把最大或最小值(本次以最大值为例)拿出来,按序排列;2,堆排序是对普通选择排序的一种优化:如果是一个稳定堆,每次在选择最大值时,只用沿着二叉树其中一个分叉去交换即可,其他分叉符合堆得特性(因是排好的稳定堆),可以看作是稳定的,不用重排交换,省去了绝大多数的比...

七月流星 488

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

八大排序算法-堆排序

基本思想 堆排序是一种树形选择排序,是对直接选择排序的有效改进。 堆的定义如下:具有n个元素的序列(k1,k2,…,kn),当且仅当满足 时称之为堆。由堆的定义可以看出,堆顶元素(即第一个元素)必为最小项(小顶堆)。 若以一维数组存储一个堆,则堆对应一棵完全二叉树,且所有非叶结点的值均不大于(或不小于)其子女的值,根结点(堆顶元素)的值是最小(或最大)的。如: (a)大顶堆序列:

Hist_花透的博客 2483

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

(Java版)八大排序算法(希尔排序,快速排序,堆排序等)

/** * 分类 ------------ 内部比较排序 * 数据结构 --------- 数组 * 最差时间复杂度 ---- 每次选取的基准都是最大(或最小)的元素,导致每次只划分出了一个分区,需要进行n-1次划分才能结束递归,时间复杂度为O(n^2) * 最优时间复杂度 ---- 每次选取的基准都是中位数,这样每次都均匀的划分出两个分区,只需要logn次划分就能结束递归,时间复杂度为O(nlogn) * 平均时间复杂度 ---- O(nlogn) * 所需辅助空间 ------ 主要是递归.

Mrbugu的博客 642

八大排序算法 —— 堆排序

堆排序 堆的概念: 堆:本质是一种数组对象。特别重要的一点性质:任意的叶子节点小于(或大于)它所有的父节点。对此,又分为大顶堆和小顶堆,大顶堆要求节点的元素都要大于其孩子,小顶堆要求节点元素都小于其左右孩子,两者对左右孩子的大小关系不做任何要求。利用堆排序,就是基于大顶堆或者小顶堆的一种排序方法。下面,我们通过大顶堆来实现。 堆排序: 堆排序利用了大根堆(或小根堆)堆顶记录的关键字最大...

C先生的博客 784

八大排序算法~堆排序

(2)for循环(从 i=最后一个结点位置开始直到i=第一个结点 结束):取根结点放于后座~即进行交换,根结点与后座最后一个位置进行交换,然后重构成新的大根堆,为什么不能for循环 调整成堆,然后取根结点,然再次调整成堆,然后再取根结点,再调整成堆。咱在对剩余的n-1个结点构建成一个新的大根堆,然后又取根结点放到后座上倒数第二个位置,然后对剩余的n-2个结点构建成一个新的大根堆,然后又取根结点放到后座上倒数第三个位置,再取根节点跟后座倒数第二个位置交换,然后重新构建新的大根堆,然后。

m0_66468899的博客 291

【八大排序算法之堆排序—Java】

堆排序 堆的结构可以分为大顶堆和小顶堆,是一个完全二叉树。 首先说明什么是完全二叉树: 若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。例如下图就不是一个完全二叉树,虽然1,2层均达到最大个数,但是第三层的节点应几种在左侧,即点7应该位于8的左子节点 其次说明什么是大顶堆和小顶堆: 每个结点的值都大于其左子节点和右子结点的值,称之为大顶堆;每个结点的值都小于其左子节点和右子结点的值,称之为小顶堆。下图即为大顶

weixin_47714239的博客 1132

八大排序算法详解——堆排序

基本思想 堆的定义n个关键字序列kl,k2,…,kn称为堆,当且仅当该序列满足如下性质之一(简称堆性质): ki≤k2i且ki≤k2i+1 或 ki≥k2i且ki≥k2i+1(1≤i≤FLOOR(n/2))若将此序列所存储的向量R[1..n]看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树:树中任一非叶结点的关键字均不大于(或不小于)其左右孩子(若 存在)结点的关键字。 小根堆:

cy__dream的博客 848
上一篇: 稠密索引与稀疏索引
下一篇: 八大排序算法——冒泡排序
Jeaforea
博客等级 码龄10年 30粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值