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

【排序算法】堆排序详解

堆排序

有关 “堆” 知识的详解可以看这里——【堆】
其他经典比较类排序算法可以看这里——【六大比较类排序算法】

1. 建堆

在之前我们了解了堆,我们都知道大顶堆和小顶堆的特点:

  • 小顶堆:任意节点的值 ≤ 其子节点的值。
  • 大顶堆:任意节点的值 ≥ 其子节点的值。

而大顶堆的根节点是整棵树中最大的数,小顶堆的根节点是整棵树中最小的数。我们就可以根据这一点来进行排序的操作。

首先既然是堆排序,那么这个数组就得先是一个堆。现在我们随机给一个数组 {27,28, 65, 25, 15, 34, 19, 49, 18, 37 }。它是无序的且不满足堆的特点。
请添加图片描述

这个时候我们就可以利用向下调整算法来对这个数组进行建堆的操作:(以建小堆为例)

请添加图片描述

// 数组建堆算法
for (int i = (n - 1 - 1) / 2; i >= 0; --i){
	AdjustDown(arr, n, i);
}

2. 排序

建好堆后,这个时候这个数组已经变成了一个小顶堆。此时最小的数在最上面,已经被选出来了。现在我们可以将这个数与最后一个数,也就是最后一个叶子节点做交换,并且之后不把这个最小的数看作是堆内的数据(不删除),再对剩下的 n − 1 n-1 n1 个数做向下调整再次构建一个小顶堆,选出次小的数,放在末尾。这样循环操作,我们就可以得到一个排好序的降序的数组。

下面是动图演示:
请添加图片描述

注意构建小顶堆最后排出来的是降序的数组,如果想要升序的数组,则需要构建大顶堆

// 向下调整法
// 建小堆
void AdjustDown(HPDataType* a, int n, int root){
    int parent = root;
    int child = 2 * parent + 1;
    while(child < n){
        // 防止没有右孩子       左右孩子比较
        if(child + 1 < n && a[child] > a[child + 1]){
            child++;  // 如果左孩子大,那就要选右孩子,因此++
        }
        // 父节点与小的那个孩子比较,如果父节点大,则交换
        if(a[parent] > a[child]){
            int temp = a[parent];
            a[parent] = a[child];
            a[child] = temp;
            parent = child;  // 更新下标
            child = 2 * parent + 1;  // 找到新的孩子然后继续比较
        }
        else{
            break;
        }
    }
}

// 堆排序(排逆序)
void HeapSort(int* a, int n){
	// 建小堆
	for (int i = (n - 1 - 1) / 2; i >= 0; --i){	
        // 建小堆和建大堆的向下调整函数内部判断条件略有不同
		AdjustDown(a, n, i);
	}
	int end = n - 1;
	// 把最大的换到最后一个位置,不把最后一个数看作堆里的
	// 每次选出剩下数中最大的
	// 从后往前放
	while (end > 0){
		int tem = a[end];
		a[end] = a[0];
		a[0] = tem;
		// 选出次大的数
		AdjustDown(a, end, 0);
		--end;
	}
}

3. 算法分析

在上一篇文章我们分析过建堆的时间复杂度为 O ( N ) O(N) O(N)

而向下调整算法的时间复杂度为 O ( l o g 2 N ) O(log_2N) O(log2N)

所以堆排序的时间复杂度为 O ( N l o g 2 N ) O(Nlog_2N) O(Nlog2N)
空间复杂度 O ( 1 ) O(1) O(1)

4. 总结对比

排序方法平均情况最好情况最坏情况辅助空间稳定性
插入排序 O ( n 2 ) O(n^2) O(n2) O ( n ) O(n) O(n) O ( n 2 ) O(n^2) O(n2) O ( 1 ) O(1) O(1)稳定
选择排序 O ( n 2 ) O(n^2) O(n2) O ( n 2 ) O(n^2) O(n2) O ( n 2 ) O(n^2) O(n2) O ( 1 ) O(1) O(1)不稳定
冒泡排序 O ( n 2 ) O(n^2) O(n2) O ( n ) O(n) O(n) O ( n 2 ) O(n^2) O(n2) O ( 1 ) O(1) O(1)稳定
希尔排序 O ( n log ⁡ n ) O(n\operatorname{log}n) O(nlogn) ~ O ( n 2 ) O(n^2) O(n2) O ( n 1.3 ) O(n^{1.3}) O(n1.3) O ( n 2 ) O(n^2) O(n2) O ( 1 ) O(1) O(1)不稳定
快速排序 O ( n log ⁡ n ) O(n\operatorname{log}n) O(nlogn) O ( n log ⁡ n ) O(n\operatorname{log}n) O(nlogn) O ( n 2 ) O(n^2) O(n2) O ( log ⁡ n ) O(\operatorname{log}n) O(logn) ~ O ( n ) O(n) O(n)不稳定
归并排序 O ( n log ⁡ n ) O(n\operatorname{log}n) O(nlogn) O ( n log ⁡ n ) O(n\operatorname{log}n) O(nlogn) O ( n log ⁡ n ) O(n\operatorname{log}n) O(nlogn) O ( n ) O(n) O(n)稳定
堆排序 O ( n log ⁡ n ) O(n\operatorname{log}n) O(nlogn) O ( n log ⁡ n ) O(n\operatorname{log}n) O(nlogn) O ( n log ⁡ n ) O(n\operatorname{log}n) O(nlogn) O ( 1 ) O(1) O(1)不稳定

文章转载自:

http://v7pYYGLz.gfjgq.cn
http://dqHpST52.gfjgq.cn
http://PQw9O5C7.gfjgq.cn
http://DD35EvTb.gfjgq.cn
http://OwSAMw1h.gfjgq.cn
http://hQX5sYUe.gfjgq.cn
http://02wV1e2Q.gfjgq.cn
http://BPxeV5hz.gfjgq.cn
http://7cuRHanD.gfjgq.cn
http://D0a53sX4.gfjgq.cn
http://AU6G799l.gfjgq.cn
http://2xy79ZDP.gfjgq.cn
http://o7XweySD.gfjgq.cn
http://P3KoLewk.gfjgq.cn
http://IsjPx5fE.gfjgq.cn
http://Hx4nZ7MK.gfjgq.cn
http://uTA3idWU.gfjgq.cn
http://CEAP4blK.gfjgq.cn
http://uDZw3uYn.gfjgq.cn
http://RJvrJvIT.gfjgq.cn
http://xypUNscR.gfjgq.cn
http://cAP8tVcl.gfjgq.cn
http://MplpMCgT.gfjgq.cn
http://e7A7Crtc.gfjgq.cn
http://ifyyJmla.gfjgq.cn
http://NWABifxe.gfjgq.cn
http://mcTPi9G2.gfjgq.cn
http://PDmB8oZC.gfjgq.cn
http://BCycSktN.gfjgq.cn
http://lk1mD4A7.gfjgq.cn
http://www.dtcms.com/a/36180.html

相关文章:

  • 基于 SpringBoot 的 “电影交流平台小程序” 系统的设计与实现
  • 推送项目 之 解决冲突
  • Claude 3.7 Sonnet 泄露,Anthropic 最先进 AI 模型即将在 AWS Bedrock 上首次亮相
  • 【NLP 26、实践 ⑥ 引入bert,判断文本中是否有特定字符出现】
  • 深入理解 Redis 设计与集群管理
  • JavaSE学习笔记26-集合(Collection)
  • Unity百游修炼(1)——FootBall详细制作全流程
  • 大模型语料库的构建过程 包括知识图谱构建 垂直知识图谱构建 输入到sql构建 输入到cypher构建 通过智能体管理数据生产组件
  • 【前端基础】Day 1 HTML
  • 【Qt】桌面应用开发 ------ 绘图事件和绘图设备 文件操作
  • 渗透小记--Docker Registry未授权访问
  • PHP_最新版PTCMS小说聚合网站系统源码+会员收费机制+深度SEO优化带自动采集+采集规则+安装教程
  • Web刷题之PolarDN(中等)
  • mysql 学习17 SQL 锁
  • Webpack打包优化
  • 浅谈 Redis 主从复制原理(二)
  • python学习第十章-post请求与get请求的区别
  • 【1】VS Code 新建上位机项目---C#基础语法
  • STM32使用NRF2401进行数据传送
  • 学习通用多层次市场非理性因素以提升股票收益预测
  • 链表(LinkedList)面试题
  • 【UCB CS 61B SP24】Lecture 11 - Inheritance 4: Iterators, Object Methods学习笔记
  • 解决VMware 安装 Ubuntu 后无法全屏的问题
  • P1113 杂务
  • opencv:距离变换 cv2.distanceTransform
  • AI手机的技术细节
  • 最小化重投影误差求解PnP
  • vue中使用地图
  • C++二叉搜索树
  • Linux-SaltStack配置