【排序算法】堆排序

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

1、什么是堆

         首先它是一颗完全二叉树,并且父结点的值大于子节点的值(最大堆)或父结点的值小于子结点的值(最小堆)。

小根堆:根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最小者的堆称为小根堆,又称最小堆。

大根堆:根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最大者,称为大根堆,又称最大堆。

2、堆排序

        利用了大根堆或最小堆堆顶记录的关键字最大或最小这一特征,使得在当前无序区中选取最大或最小的关键字变得简单。

     用大根堆排序的基本思想

  ① 先将初始文件R[0..n-1]建成一个大根堆,此堆为初始的无序区。(max_heapify()函数完成建立最大堆的功能)

  ② 再将关键字最大的记录R[0](即堆顶)和无序区的最后一个记录R[n-1]交换,由此得到新的无序区R[0..n-2]和有序区R[n-1],且满足R[0..n-2].keys≤R[n-1].key

  ③由于交换后新的根R[0]可能违反堆性质,故应将当前无序区R[0..n-2]调整为堆。然后再次将R[0..n-2]中关键字最大的记录R[0]和该区间的最后一个记录R[n-2]交换,由此得到新的无序区R[0..n-3]和有序区R[n-2..n-1],且仍满足关系R[0..n-3].keys≤R[n-2..n-1].keys,同样要将R[0..n-3]调整为堆。

  ……

  直到无序区只有一个元素为止。(HeapSort()对最大根堆进行排序)

 可得:若升序排列,应该建立最大堆,若降序排列,建立最小堆。

代码如下:

// Array是待调整的堆数组,i是待调整的数组元素的位置,即待调整的父结点,size是数组的长度,即结点总数 
 void heapify(int Array[],int i,int size)
 {
    if(i<size)
	{
		int left=2*i+1;
		int right=2*i+2;
		int largest=i;//假设最大的节点为父结点
		//确定三个结点中的最大结点
		if(left<size)
		{
			if(Array[largest]<Array[left])
				largest=left;
		}
		if(right<size)
		{
          if(Array[largest]<Array[right])
			  largest=right;
		}

		//开始交换父结点和最大的子结点
       if(largest!=i)
	   {
		   int temp=Array[largest];
		   Array[largest]=Array[i];
		   Array[i]=temp;
		   heapify(Array,largest,size);//对已经调整的结点做同样的交换
	   }
	}
 }
 //注:上面函数的调用作了如下假设:待调整的i结点所有的子结点都满足堆的条件,故调用该函数应该
// 从最后一个结点开始调整为最大堆建堆过程,建立最大堆
 void max_heapify(int Array[],int size)//调整最大堆,从最后一个结点开始调整
 {
	 int i;
	 for(i=size-1;i>=0;i--)
		 heapify(Array,i,size);
	 
 }


// 堆排序算法,排序过程
void HeapSort(int Array[],int size) 
{
 int i;
 for(i=size-1;i>=0;i--)
 {
	 max_heapify(Array,i+1);//每次建立最大堆,将它的大小减1,砍断
       //将根结点(最大结点)与最后一个结点交换
	 int temp=Array[0];
	 Array[0]=Array[i];
	 Array[i]=temp;
 }
	
}

int main()
{
    
	int a[]={10,23,8,2,52,35,7,1,12};
	int length=sizeof(a)/sizeof(int);
	printf("数组元素如下所示: \n");
     for(int i=0;i<length;i++)
        printf("%4d",a[i]);
    printf("\n");


    printf("创建好堆以后的数组元素如下所示: \n");
	max_heapify(a,length);
    for(i=0;i<length;i++)
        printf("%4d",a[i]);
    printf("\n");
   

    HeapSort(a,length);    
 printf("经过排序后的堆,数组元素如下所示 : \n");
for(i=0;i<length;i++)
     printf("%4d",a[i]);
    printf("\n");
    


	return 0;
}

   注:堆排序的最坏时间复杂度为O(nlogn)。堆排序的平均性能较接近于最坏性能。

  由于建初始堆所需的比较次数较多,所以堆排序不适宜于记录数较少的文件。

  堆排序是就地排序,辅助空间为O(1),

  它是不稳定的排序方法。

【排序算法】之堆排序 特别说明,这里的序列都是从1开始。 1、什么是堆 对于n个元素的序列{R1, … , Rn}当且仅当满足下列关系之一时,称之为堆: (1) Ri (2) Ri >= R2i+1 且 Ri >= R2i+2 (大根堆) 2、什么是堆排序 堆排序是一种树形选择排序,它的特点是在排序的过程中,将r[1..n]看成是一棵完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间 阅读详情

相关推荐

漫谈经典排序算法:一、从简单选择排序到堆排序的深度解析

1、序言 这是《漫谈经典排序算法系列》第一篇,该篇从最简单的选择排序算法谈起,由浅入深的详细解析两种选择排序算法的过程及性能比较。逐步揭露选择排序的本质及其基本思想。 各种排序算法的解析请参考如下: 《漫谈经典排序算法:一、从简单选择排序到堆排序的深度解析》 《漫谈经典排序算法:二、各种插入排序解析及性能比较》 《漫谈经典排序算法:三、冒泡排序 && 快速排序》 《漫谈经典排序算

Touch_2011的专栏 3万+

堆排序(升序&降序)

创建大/小根堆,完成升序/降序排序

lxylxylxy的博客 3664

排序算法之 堆排序

堆排序 By yujian 选择排序算法,是选择最值,然后将其调整到合适位...

目前打算换一个工作,有招聘windows c++方向的也欢迎联系,北京、济南 最好 1万+

堆排序--升序与降序

现有一个数组arr,我们需要按升序来对它进行排序。 arr[]={9,1,3,5,7,2,4,6,8} 在建堆之前,我们需要先考虑一个问题--是建大堆还是建小堆,以及建堆时需要向上调整还是向下调整? 首先我们假设建大堆,而建大堆又分为两种情况: 如果是向上调整的话只需要我们从第二个元素开始,依次进行向上调整,直至最后一个元素。 若是选择向下调整的话,只需要从最后一个元素的父节点开始即可。 因为向上调整的时间复杂度为O(N*logN),而向下调整的复杂度为O(N),所以我们较多使用向下调整。

zh01230的博客 2588

【堆排序】十大排序算法之堆排序

堆,是一种数据结构,它是一个完全二叉树的数据结构。什么是完全二叉树???要了解完全二叉树,就需要知道什么是二叉树???二叉树案例:满二叉树,所谓的满二叉树就是指:一颗具有【n】个结点的满二叉树,具有如下特点:满二叉树案例:完全二叉树,除了最后一层结点,其余每层结点都是满二叉树,并且最后一层结点是从左往右依次展示的。完全二叉树,首先它必须是一颗二叉树,然后这颗二叉树满足如下特点:完全二叉树,可以看作是除了最后一层之外,其余结点都是满二叉树的树。完全二叉树具有如下特点:完全二叉树案例:堆就是利用了完全二叉树..

✅ Java 开发工程师 1425

5分钟搞定:用Pyannote和Whisper实现带说话人分离的语音转文字(附完整代码)

本文详细介绍了如何快速构建一个集成了说话人分离功能的语音转文字系统。通过结合OpenAI的Whisper模型进行高精度语音识别和Pyannote模型实现说话人分离,并提供了完整的代码实现、环境搭建指南以及核心的对齐与合并逻辑,帮助开发者高效处理会议录音、访谈等多说话人音频,实现自动化转录。

threejs5artist的博客 635

堆排序算法(排升序)分析研究

堆算法详解

m0_74949249的博客 950

保姆级教程:用NovAtel Inertial Explorer 8.7搞定GNSS/INS紧组合后处理(附避坑指南)

本文提供NovAtel Inertial Explorer 8.7的GNSS/INS紧组合后处理全流程教程,涵盖环境准备、数据转换、基站坐标解算及紧组合处理等关键步骤。特别针对零基础用户,分享实用技巧和常见陷阱,帮助高效完成高精度组合导航数据处理,适用于测绘、自动驾驶等领域。

weixin_42614269的博客 279

数据结构之堆排序(升序和降序)

关于堆这种数据结构,可以观看这篇文章【数据结构之堆】,要是不了解的话。 1 升序排序 升序排序使用最大堆,降序排序排序使用最小堆,并不是说只能这样用,只是这种设计会比较简洁。 这里以升序排序为例,每次需要将当前堆调整为最大堆,然后将堆顶元素(数组第0个元素)和最后一个元素(第size-1个元素)进行交换。然后对前面的(n-1)个元素调整成最大堆, 但是需要注意:此时,堆相当于删除了对顶元素,然后最后一个元素换到堆顶的位置,此时需要重新调整,但是堆的大小也减小了1。所以,此时调整的应该是n-1个元素的堆。 p

麦田里的守望者 5555

自制JS某课脚本

根据实际需求自制网页讯网刷题脚本,绕过人脸,弹窗,答题,实现自动化运行

2301_81243054的博客 3458

用STM32L552驱动AD9102:一个硬件工程师的实战避坑指南(附完整代码)

本文详细介绍了如何使用STM32L552微控制器驱动AD9102任意波形发生器芯片,从硬件设计到波形生成的完整实战指南。内容包括电源架构、时钟电路设计、输出调理电路等关键硬件设计要点,以及软件驱动架构、波形存储优化和典型波形生成实例。通过实战经验分享,帮助硬件工程师避开常见设计陷阱,提升开发效率。

weixin_30889885的博客 333

排序算法上——插入,希尔,选择,堆排序

在希尔排序开始时增量较大,分组较多,每组的记录数目少,n小,此时直接插入最好和最坏时间复杂度n2差距很小,故各组内直接插入较快,后来增量di逐渐缩小,分组数逐渐减少,而各组的记录数目逐渐增多,但由于已经按di-1作为距离排过序,使文件较接近于有序状态,所以新的一趟排序过程也较快。2. 然而在排序的时候,时间消耗过于庞大,因为在挪动元素时,会把堆内的序列和关系打乱,因此应该建大堆,然后利用算法进行调整。1.希尔排序的核心在于对数组进行预排序,值得注意的是,预排序只是让数组相对有序,而非达到真正的有序状态。

2303_81060385的博客 1512

llama2-7b下载并转llama-2-7b-hf

④输入https://github.com/huggingface/transformers/blob/main/src/transformers/models/llama/convert_llama_weights_to_hf.py会下载 convert_llama_weights_to_hf.py 文件,我们需要用到这个文件将llama2-7b转成llama-2-7b-hf。③下载完之后是这四个文件,这里我是在windows操作系统中安装的WSL,没有linux操作系统,没办法。

wenling54321的博客 1030

排序算法——堆排序

排序算法——堆排序 堆排序是利用堆这种数据结构所设计的一种排序算法。堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。升序采用大顶堆,降序采用小顶堆。大顶堆:arr[i] > >= arr[2i+1] && arr[i] >= arr[2i+2];小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]。 例如一

程序员之道 1581

GEE:连续变化检测 CCDC 提取断点信息(干扰时间、干扰幅度、干扰次数)

本文将介绍在 Google Earth Engine (GEE) 平台上连续变化检测与分类(Continuous Change Detection and Classification, CCDC)提取扰动时间、干扰幅度、干扰次数信息,并下载到本地的代码。

养乐多的博客 1945

RK3588&RK3576实现 HW-ID DTB(动态加载不同的Kernel DTB)功能

RK平台的U-Boot⽀持检测硬件上的GPIO或者ADC状态动态加载不同的Kernel DTB,暂称为HW-ID DTB(Hardware id DTB)功能。

Wynter 849

十大经典排序算法-堆排序算法详解

一、什么是堆排序 1.概念 堆排序(Heapsort)是利用二叉堆的概念来排序的选择排序算法,分为两种: 升序排序:利用最大堆进行排序 降序排序:利用最小堆进行排序 2.算法原理 给定一个最大堆如下图所示,以该最大堆进行演示堆排序 首先,删除堆顶元素10(即最大的元素),并将最后的元素3补充到堆顶,删除的元素10,放置于原来最后的元素3的位置 根据二叉堆的自我调整,第二大的元素9会成为二叉堆新的堆顶 删除元素9,元素8成为最大堆堆顶 删除元素8,元素7成为最大堆堆顶 依次删除最大元素,直至所有

qq_35344198的博客 1万+

Vue3 - 解决报错 Uncaught (in promise) DOMException: Failed to execute ‘insertBefore‘ on ‘Node‘: The node

vue3,报错,vue3报错,Uncaught(inpromise)DOMException:Failedtoexecute'insertBefore'on'Node':Thenodebeforewhichthenewnodeistobeinsertedisnotachildofthisnode,如何解决这个错误,动态渲染,v-if,v-show,insertBefore,详细解决方法,vue3未能在“Node”上执行“insertBefore”:要插入

🏆 前端领域优质创作者 1万+

【排序算法】选择排序、堆排序

堆排序是一种基于堆(Heap)数据结构的排序算法。最大堆:每个节点的值都大于或等于其子节点的值。根节点是最大值。最小堆:每个节点的值都小于或等于其子节点的值。根节点是最小值。首先将无序数组构建为一个最大堆。然后,将堆顶(即最大值)与数组的最后一个元素交换,缩小堆的范围,对剩下的元素继续调整成最大堆,直到排序完成。

2301_76677973的博客 2940

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

排序算法 -堆排序

堆排序

shiyue 882

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

排序算法之堆排序

简介         堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。         堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即父节点结点的键值或索引总是小于(或者大于)它的子节点。 堆的概念         在介绍堆排序之前,简单介

qq_44290077的博客 3570

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

上一篇: 【编程之美】读书笔记:求1到N之间整数中出现1的个数
下一篇: 【编程之美】读书笔记:寻找最大的K个数
xiaoding133
博客等级 码龄19年 415粉丝 159原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值