高效排序算法——堆排序腾讯云开发者社区

堆是一种特殊的完全二叉树,它有以下特点:

最大堆:任意节点的值都大于或等于其子节点的值。

最小堆:任意节点的值都小于或等于其子节点的值。

堆排序的基本思想是利用堆的性质,将待排序的序列构建成一个堆,然后每次从堆顶取出最大(或最小)的元素放到已排序的序列中,再将剩余元素重新构建成一个堆,循环执行这个过程,直到排序完成。

堆排序的具体步骤如下:

构建最大堆或最小堆:从最后一个非叶子节点开始,依次向上调整每个节点,使其满足堆的性质。

取出堆顶元素:将堆顶元素与最后一个元素交换,然后将堆的大小减1。

重新构建堆:对交换后的堆顶元素进行向下调整操作,使其满足堆的性质。

重复执行步骤2和步骤3,直到堆的大小为1。

堆排序的实现可以分为两个部分:堆的构建和堆的调整

堆的构建是将一个无序的序列构建成一个堆的过程。从最后一个非叶子节点开始,对每个节点进行向下调整操作,使其满足堆的性质。

以构建最大堆为例,具体实现步骤如下:

从最后一个非叶子节点开始,依次向上调整每个节点。

对于每个节点,比较其与左右子节点的大小,如果大于左右子节点的值,则不需要调整;否则,将该节点与左右子节点中较大的节点交换位置,并继续向下调整交换后的节点,直到满足堆的性质。

在构造有序堆时,我们开始只需要扫描一半的元素(n/2-1 ~ 0)即可,因为(n/2-1)~0的节点才有子节点,n=8,(n/2-1) = 3 即3 2 1 0这个四个节点才有子节点

所以代码4~6行for循环的作用就是将3 2 1 0这四个节点从下到上,从右到左的与它自己的子节点比较并调整最终形成大顶堆,过程如下:

第一次for循环将节点3和它的子节点7 8的元素进行比较,最大者作为父节点(即元素60作为父节点)

第二次for循环将节点2和它的子节点5 6的元素进行比较,最大者为父节点(元素80作为父节点)

第三次for循环将节点1和它的子节点3 4的元素进行比较,最大者为父节点(元素70作为父节点)

第四次for循环将节点0和它的子节点1 2的元素进行比较,最大者为父节点(元素80作为父节点)

注意,元素20和元素80交换后,20所在的节点还有子节点,所以还要再和它的子节点5 6的元素进行比较,这就是28行代码 i = j 的原因

有序堆已构造好

下面进行while循环

堆顶元素80和尾40交换后-->调整堆

堆顶元素70和尾30交换后-->调整堆

堆顶元素60尾元素20交换后-->调整堆

其他依次类推,最终已排好序的元素如下:

堆的调整是将堆顶元素与最后一个元素交换后,对堆顶元素进行向下调整操作的过程。

以调整最大堆为例,具体实现步骤如下:

将堆顶元素与最后一个元素交换位置。

对交换后的堆顶元素进行向下调整操作,与左右子节点中较大的节点交换位置,直到满足堆的性质。

堆排序的性能主要受到两个因素的影响:构建堆的过程和调整堆的过程。

构建堆的优化:

构建堆的过程中,可以选择从最后一个非叶子节点开始,直接进行向下调整操作,而不是每个节点都向上调整。这样可以减少调整的次数,提高构建堆的效率。

调整堆的优化:

调整堆的过程中,可以使用堆的性质进行剪枝。即,在每次向下调整时,只与左右子节点中较大的节点进行比较交换,而不是与每个子节点都进行比较。这样可以减少比较和交换的次数,提高调整堆的效率。

同时,可以使用大顶堆和小顶堆相结合的方式进行排序。即,先构建一个大顶堆,然后将堆顶元素与最后一个元素交换,然后对交换后的堆顶元素进行向下调整操作得到小顶堆,再将堆顶元素与倒数第二个元素交换,重复执行这个过程,直到排序完成。这样可以减少每次调整堆的时间。

堆排序是一种高效的排序算法,通过构建最大堆或最小堆来实现排序。它的时间复杂度为O(nlogn),适用于大规模数据的排序。实现堆排序主要包括堆的构建和堆的调整两个过程,可以根据具体情况进行优化,提高排序的效率。同时,堆排序也可以与其他排序算法相结合,以达到更好的排序效果。

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