使用堆排序
堆排序要求我们从给定的元素列表中建立一个堆,然后持续检查堆属性,使整个堆始终保持排序状态。与普通堆不同的是,一旦新插入的值满足条件,我们就会停止检查堆属性,而在堆排序过程中,我们会继续对下一个元素进行检查。堆排序的伪代码如下所示:
Heapsort(A as array)
BuildHeap(A)
for i = n-1 to 0
swap(A[0], A[i])
n = n - 1
Heapify(A, 0)
BuildHeap(A as array)
n = elements_in(A)
for i = floor(n/2) to 0
Heapify(A,i)
Heapify(A as array, i as int)
left = 2i+1
right = 2i+2
max = i
if (left <= n) and (A[left] > A[i])
max = left
if (right<=n) and (A[right] > A[max])
max = right
if (max != i)
swap(A[i], A[max])
Heapify(A, max)
伪代码显示,每当我们试图对元素列表进行排序时,启动过程都取决于堆的构建。每次向堆中添加一个项目时,我们都会通过 heapify
函数检查该项目是否满足堆属性。一旦堆构建完成,我们就会检查所有元素的堆属性。现在,让我们根据前面的伪代码来实现堆排序:
Unresolved include directive in modules/ROOT/pages/ch10/ch10-06.adoc - include::example$Chapter10/3.php[]
现在让我们使用 heapSort
函数对数组进行排序。由于我们是以引用方式传递参数,因此函数不会返回任何内容。实际数组将在操作结束时进行排序:
Unresolved include directive in modules/ROOT/pages/ch10/ch10-06.adoc - include::example$Chapter10/3.php[]
如果我们运行这段代码,命令行会有如下输出:
9 26 34 37 44 65 86 129 143
如果我们想将排序改为降序,只需更改 heapify
函数中的比较值即可。如果我们考虑一下 heapSort
算法的时间和空间复杂度,就会发现堆排序是复杂度最好的排序算法:
最好时间复杂度 |
\$Ω(nlog(n))\$ |
最坏时间复杂度 |
\$O (nlog(n))\$ |
平均时间复杂度 |
\$Θ(nlog(n))\$ |
空间复杂度(最差情况) |
\$O(1)\$ |
与合并排序相比,堆排序具有更好的空间复杂性。因此,许多开发人员更喜欢使用堆排序来对项目列表进行排序。