【排序算法】之堆排序

特别说明,这里的序列都是从1开始。

1、什么是堆

对于n个元素的序列{R1, … , Rn}当且仅当满足下列关系之一时,称之为堆:

(1) Ri <= R2i+1 且 Ri <= R2i+2 (小根堆)

(2) Ri >= R2i+1 且 Ri >= R2i+2 (大根堆)

2、什么是堆排序

堆排序是一种树形选择排序,它的特点是在排序的过程中,将r[1..n]看成是一棵完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间的内在联系,在当前无序区中选择关键字最大或者最小的记录。

堆实际上是一棵以顺序方式存储的完全二叉树,并满足如下性质:树中任一非叶子结点的关键字均不大于或者不小于其左右孩子的关键字。例如关键字序列(12, 36, 24, 85, 47, 30, 53, 91)和(96, 83, 27, 28, 11, 09)分别是满足上述性质的小根堆和大根堆。第一个序列对应的二叉树如下图:

这里写图片描述

显然,堆中任一子树也是堆。

3、推排序的基本操作

堆排序利用了大根堆(或小根堆)中堆顶记录的关键字最大(或最小),这一特性,使得在当前无序区中选取最大(最小)的记录变得简单。下面以大根堆为例说明堆排序的基本过程。

大根堆排序算法的基本操作,初始化操作是按堆的定义将数组R[1..n]调整为初始堆。每一趟排序的基本操作是,将当前无序区的堆顶记录r[1]和该区

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
选择排序算法: 1. 从数组中选择最小的元素,将其放置在数组的起始位置。 2. 在剩余的元素中选择最小的元素,将其放置在已排序元素的末尾。 3. 重复步骤2直到所有元素都已排序。 代码实现: ``` function selectionSort(arr) { for (let i = 0; i < arr.length - 1; i++) { let minIndex = i; for (let j = i + 1; j < arr.length; j++) { if (arr[j] < arr[minIndex]) { minIndex = j; } } if (minIndex !== i) { [arr[i], arr[minIndex]] = [arr[minIndex], arr[i]]; } } return arr; } ``` 堆排序算法: 1. 构建一个最大堆(或最小堆)。 2. 将堆顶元素与最后一个元素交换,然后将堆的大小减1。 3. 对新的堆顶元素进行堆化,重复步骤2和3直到堆的大小为1。 代码实现: ``` function heapSort(arr) { buildMaxHeap(arr); let heapSize = arr.length; for (let i = arr.length - 1; i > 0; i--) { [arr[0], arr[i]] = [arr[i], arr[0]]; heapSize--; maxHeapify(arr, 0, heapSize); } return arr; } function buildMaxHeap(arr) { const heapSize = arr.length; for (let i = Math.floor(heapSize / 2); i >= 0; i--) { maxHeapify(arr, i, heapSize); } } function maxHeapify(arr, i, heapSize) { const left = 2 * i + 1; const right = 2 * i + 2; let largest = i; if (left < heapSize && arr[left] > arr[largest]) { largest = left; } if (right < heapSize && arr[right] > arr[largest]) { largest = right; } if (largest !== i) { [arr[i], arr[largest]] = [arr[largest], arr[i]]; maxHeapify(arr, largest, heapSize); } } ``` 选择排序算法的时间复杂度为$O(n^2)$,堆排序算法的时间复杂度为$O(n\log n)$。虽然堆排序的时间复杂度比选择排序更优,但是堆排序的常数项较大,因此在实际应用中需要根据具体情况选择合适的排序算法

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值