堆排序

堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序可以说是一种利用堆的概念来排序的选择排序。分为两种方法:

创建一个堆 H[0……n-1];

把堆首(最大值)和堆尾互换;

把堆的尺寸缩小 1,并调用 shift_down(0),目的是把新的数组顶端数据调整到相应位置;

重复步骤 2,直到堆的尺寸为 1。

假设有一个待排序的列表 [4, 10, 3, 5, 1],堆排序的过程如下:

构建最大堆:

初始列表:[4, 10, 3, 5, 1]。

从最后一个非叶子节点开始,逐步调整堆:

调整节点 5:[4, 10, 3, 5, 1](无需调整)。

调整节点 10:[4, 10, 3, 5, 1](无需调整)。

调整节点 4:[10, 5, 3, 4, 1]。

最终最大堆:[10, 5, 3, 4, 1]。

交换堆顶元素:

将堆顶元素 10 与最后一个元素 1 交换,列表变为 [1, 5, 3, 4, 10]。

堆的大小减 1,已排序部分为 [10]。

调整堆:

对新的堆顶元素 1 进行下沉操作:

比较 1 和其子节点 5、3,将 1 与 5 交换。

列表变为 [5, 1, 3, 4, 10]。

继续比较 1 和其子节点 4,将 1 与 4 交换。

列表变为 [5, 4, 3, 1, 10]。

调整后的堆:[5, 4, 3, 1]。

重复步骤:

将堆顶元素 5 与最后一个元素 1 交换,列表变为 [1, 4, 3, 5, 10]。

堆的大小减 1,已排序部分为 [5, 10]。

对新的堆顶元素 1 进行下沉操作:

比较 1 和其子节点 4、3,将 1 与 4 交换。

列表变为 [4, 1, 3, 5, 10]。

调整后的堆:[4, 1, 3]。

继续重复:

将堆顶元素 4 与最后一个元素 3 交换,列表变为 [3, 1, 4, 5, 10]。

堆的大小减 1,已排序部分为 [4, 5, 10]。

对新的堆顶元素 3 进行下沉操作:

比较 3 和其子节点 1,无需交换。

调整后的堆:[3, 1]。

最终步骤:

将堆顶元素 3 与最后一个元素 1 交换,列表变为 [1, 3, 4, 5, 10]。

堆的大小减 1,已排序部分为 [3, 4, 5, 10]。

堆的大小为 1,排序完成。

构建最大堆:O(n)。

每次调整堆:O(log n),总共需要调整 n-1 次。

O(1),堆排序是原地排序算法,不需要额外的存储空间。

优点:

原地排序,不需要额外的存储空间。

缺点:

不稳定排序算法(可能改变相同元素的相对顺序)。

对于小规模数据,性能可能不如插入排序等简单算法。

大规模数据集的排序。

对性能要求较高的场景。

适合内存排序(不适合外部排序)。

艾孜尔江

上方又没些 C# 的堆排序,艾孜尔江补充如下:

艾孜尔江

大兵小将

堆排序是不稳定的排序!

既然如此,每次构建大顶堆时,在 父节点、左子节点、右子节点取三者中最大者作为父节点就行。我们追寻的只是最终排序后的结果,所以可以简化其中的步骤。

我将个人写的 Java 代码核心放在下方,有兴趣的同学可以一起讨论下:

THE END
0.[DataStructure&Algorithm]选择排序+锦标赛排序+堆排序树形选择排序(锦标赛排序) 基本思想 第一轮排序,把所有记录作为树的最后一层,两两分组(如果共有奇数个记录,则最后补上∞),取其中较小的记录作为倒数第二层 依次类推,最终得到的根结点即为这一轮中的最小值 第二轮排序,将上一轮中的最小值用∞表示,重新构造树,新的根结点即为这一轮的最小值 jvzquC41yy}/ewgnqiy/exr1dtkbm6icypt0r8>:959467mvon
1.外排序相关算法(插入排序锦标赛排序归并排序)Algorithm:C++语言实现之内排序、外排序相关算法(插入排序 、锦标赛排序、归并排序) 目录 一、内排序 1、插入排序 2、锦标赛排序 3、归并排序 二、外排序 1、过程 一、内排序 1、插入排序 2、锦标赛排序 3、归并排序 4、堆排序是利用堆的性质进行的一种选择排序 jvzquC41{wtzcwnw0drpi7hufp4og}4ctvodnn4fgvgjn|4:35?68?8
2.C语言选择排序和堆排序C语言---选择排序和堆排序 前言 堆排序是选择排序的一种,今天我们讲解一下堆排序和简单选择排序 一、简单选择排序 1.简介 选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。jvzquC41fg|fnxugt0gmk‚zp0eun1jwvkerf1:767:86
3.常见排序算法(二)(选择排序)选择排序包括什么类型选择排序分为三种,直接选择排序、树形选择排序(锦标赛排序)、堆排序(大根堆、小根堆)。直接选择排序和堆排序是不稳定排序,树形选择排序是稳定排序。 直接选择排序 通过设置哨位,将哨位位置的数与哨位之后(包括哨位)的序列中最小的数进行交换,然后哨位递增,直到哨位到达数组中最后一个数为止。 jvzquC41dnuh0lxfp0tfv8x{uwqfjjs1ctzjeuj1fgzbkux174<73?=3
4.Java编程实现数组排序——(三)选择排序树形选择排序又称为锦标赛排序,它首先对n个记录的关键字进行两两比较,然后在其中n/2个较小者当中再进行两两比较,反复进行,直到选出最小的关键字为止。树形选择排序存在着需要辅助存储空间较多以及多余比较的缺点,其时间复杂度为O(nlogn) 。三、堆排序jvzquC41dnuh0lxfp0tfv8yjktzfgwdujkybp8ftvkimg8igvcomu8:4;5=83B
5.选择排序腾讯云开发者社区分类:选择排序(选择排序,堆排序,平滑排序,笛卡尔树排序,锦标赛排序,圈排序)思想: 1、从左至右遍历,找到最小(大)的元素,然后与第一个元素交换。 2、从剩余未排序元素中继续寻找最小(大)元素,然后与第二个元素进行交换。 3、以此类推,直到所有元素均排序完毕jvzquC41enuvf7ygpekov7hqo1jfxnqqrgx0c{ykenk03:6496;
6.数据结构堆排序+TOPK问题(了解游戏排行底层原理)通过对两种建堆方式的比较更建议使用向下调整建堆但是向上调整建堆更容易理解看个人情况 🌏2.1 向上调整建堆: 🌏2.2 向下调整建堆: 🌟三、堆排序的时间复杂度:O(N*logN) 🌟四、呼应一下上章节的部分:利用堆使数据有序(不建议) 利用创建的堆数组排序:我们可以采用下面这种方法 — 先建堆(NlogN)太麻烦jvzquC41fg|fnxugt0gmk‚zp0eun1jwvkerf1:784489
7.算法与数据结构堆排序&&TOPK问题建堆和堆删除中都用到了向下调整,因此掌握了向下调整,就可以完成堆排序。 堆排序代码----->升序:建大堆 堆排序是通过建立一个大顶堆或小顶堆,然后将堆顶元素与末尾元素交换,并重新调整堆结构,这样重复地交换和调整得到有序序列。在升序排序时,我们希望第一个元素是最大的,所以需要建立大顶堆,这样堆顶元素就是当前所有元素中的最大值。 /jvzquC41fg|fnxugt0gmk‚zp0eun1jwvkerf1:9976:3
8.排序算法详解:选择排序与堆排序本文深入探讨了排序算法中的选择排序与堆排序,包括锦标赛排序、堆的特性、排序思路以及代码实现。重点突出算法核心概念与优化策略。 排序算法中的几个基本概念: 1.内部排序和外部排序 内部排序:将所有的排序记录都存储于计算机随机存储器中的排序过程; 外部排序:排序记录的数量过大,以致于不能将所有的排序记录一次性读jvzquC41dnuh0lxfp0tfv8mgasobq8ftvkimg8igvcomu8=;39>92
9.优先级队列——二叉堆多叉堆堆排序与锦标赛树这使得堆适合在插入、删除时局部调整,而不需要全局排序。 二、完全二叉堆的操作 1.插入操作 插入操作步骤 二叉堆要插入一个节点时,总是插在完全二叉树的最后一个位置(A[n]A[n]A[n]位置上)。 若在最小堆中插入一个节点,则插入节点后与父节点进行比较,若小于父节点则将该节点**“上浮”**,然后继续与父jvzquC41dnuh0lxfp0tfv87523e93>8384<0c{ykenk0fnyckny03=<586?9;
10.排序算法详解常用排序(二) 本文详细介绍了选择排序、锦标赛排序、堆排序、归并排序和基数排序等常见排序算法的工作原理及其实现过程,包括它们的时间复杂度和应用场景。 选择排序 选择排序说的是:每一趟在后面没有排序n-i个元素中,选择一个最小的放在第 i 个位置上,接下来选择i+1位置上的元素,一共需要执行n-2趟操作,他的jvzquC41dnuh0lxfp0tfv8vsa5:74B>::1gsvrhng1jfvjnnu1;45?>956