堆排序

news/2024/9/28 21:25:58

定义

堆是一棵完全二叉树。分为大顶堆和小顶堆
大顶推:所有节点都大于等于它的两个子节点
小顶堆:所有节点都小于等于它的两个子节点

伪代码

推排序步骤,以升序排列为例,用大顶堆。(降序排列,用小顶堆)

  1. 构建大顶推
  2. 把堆顶元素和堆尾元素交换,此时堆尾元素是最大的,堆的大小减一
  3. 堆顶元素下沉到指定位置
  4. 重复2-3步,直到堆的大小为1

关键在于如何构建一个大顶堆(对节点进行下沉):
从最后一个非叶子节点开始;
逐个检查每个节点,如果一个节点的值小于其子节点的值,我们就将它与较大的子节点交换位置;
交换后,这个交换后的节点可能导致不满足堆的特性,因此还需要继续下沉(Heapify)

举个例子

需要注意的是:对于一个完全二叉树
它的最后一个非叶节点下标是 Math.floor(len/2) - 1,len是二叉树的节点个数
下标为i的节点,它的左子节点是2*i+1, 右子节点是2*i+2

比如说对于[5,2,7,3,6,1,4]
最后一个非叶子节点下标是Math.floor(len/2) - 1=2, 也就是说最后一个非叶子节点是7, 构建最大堆的过程如下:

时间复杂度

O(nlogn)

实现

function heapSort(arr) {// 构建最大堆let n = arr.length;for(let i = Math.floor(n/2 - 1); i>=0;i--) {heapify(arr, n, i) // 把下标为i的节点放到合适的位置上}while(n>1) {// 交换堆顶元素和堆尾元素[arr[0], arr[n-1]] = [arr[n-1], arr[0]]// 堆的个数减一n--// 把堆顶元素放到合适的位置heapify(arr, n, 0)}
}function heapify(arr, n, i) {let largestIndex = ilet leftIndex = 2 * i + 1let rightIndex = 2 * i + 2if(leftIndex < n && arr[leftIndex] > arr[largestIndex]) {largestIndex = leftIndex}if(rightIndex < n && arr[rightIndex] > arr[largestIndex]) {
        largestIndex = rightIndex
    }if(largestIndex!==i) {[arr[i], arr[largestIndex]] = [arr[largestIndex], arr[i]]heapify(arr, n, largestIndex)}
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

AURIX™ Development Studio1.10.2(ADS)安装使用教程

以TC264系列MCU为例,介绍安装与使用AURIX™ Development Studio1.10.2的方法。零、介绍 AURIX™ Development Studio是Infineon为TriCore™-based AURIX™ microcontroller系列车规单片机设计的一款免费IDE(集成开发环境),基于Eclipse IDE开发。其包含了C编译器、TASKING调试…

随机森林分类模型 0基础小白也能懂(附代码)

随机森林分类模型 原文链接 啥是随机森林 随机森林是一种由决策树构成的(并行)集成算法,属于Bagging类型,通过组合多个弱分类器,最终结果通过投票或取均值,使得整体模型的结果具有较高的精确度和泛化性能,同时也有很好的稳定性,广泛应用在各种业务场景中。随机森林有如…

Redis组件介绍(六)

今天学习redis最后的知识写在前面 今天学习redis最后的知识。 Redis 的发布与订阅 发布/订阅模式 Redis 提供了两种发布/订阅模式:基于频道 (Channel) 的发布/订阅 基于模式 (Pattern) 的发布/订阅相关命令订阅频道 subscribe channel [channel ...]订阅给定的一个或多个频道。…

prometheus学习笔记之集群内服务发现环境准备

一、环境介绍主要演示prometheus在k8s集群中如何通过服务自动去发现k8s集群自有服务及其他服务发现场景,后续会演示集群外部署prometheus自动发现k8s服务并获取数据创建监控使用的namespaceskubectl create ns monitoring配置docker可以下载镜像[root@k8s-master deploy]# cat…

使用列表推导式实现嵌套列表的平铺

先遍历列表中嵌套的子列表,然后再遍历子列表的元素并提取出来作为最终列表中的元素 a=[[1,2,3],[4,5,6],[7,8,9]] 通过列表推导式[c for b in a for c in b],我们首先将a中的每个子列表(这里用变量b表示) 遍历出来,然后对每个b进行遍历,提取出它的每个元素(这里用变量c表…

章10——面向对象编程(高级部分)——两种单例模式

代码如下: //单例模式 //instance--实例 //该篇中记录了饿汉模式和懒汉模式 public class HungryMan {public static void main(String[] args) {Single01.say();Single02.say();} }class Single01{//只能有instance这一个实例。private Single01(){System.out.println("…

列表操作示例

首先先定义一个列表,列表是写在[]里,用逗号隔开的,元素是可以改变的 列表的截取语法结构是:变量[头下标:尾下标] L = [abc,12,3.45,python,2.789] 输出完整列表 print(L) 输出列表的第一个元素 print(L[0]) 将列表的第一个元素修改为‘a’ L[0]=a 将列表的第2个元素到第3个…

如何设计真正的实时数据湖?

通过剖析“以湖代仓”观点的认知误区,本文提出了数据的流表二象性理论,并基于“流驱表”理念指出了湖仓融合的正确发展方向——利用流式计算加速湖内仓的数据流转,落地真正的实时数据湖。汽车制造行业在企业数据管理方案上的探索已有数十年之久,本文以辩证的视角回顾了这段…