原理:
由输入的无序数组构造一个最大堆,作为初始的无序区
把堆顶元素(最大值)和堆尾元素互换
把堆(无序区)的尺寸缩小1,并调用heapify(A, 0)从新的堆顶元素开始进行堆调整
重复步骤2,直到堆的尺寸为1
<?php
/**
* 堆排序
* 数据结构----------------数组
* 最差时间复杂度-----------O(nlogn)
* 最优时间复杂度-----------O(nlogn)
* 平均时间复杂度-----------O(nlogn)
* 空间复杂度--------------O(1)
* 稳定性-----------------不稳定
*/
$arr = [1, 3, 34, 2, 32, 2, 78, -43, 53, -35, 0];
$len = count($arr);
function Swap(&$arr, $i, $j)
{
$temp = $arr[$i];
$arr[$i] = $arr[$j];
$arr[$j] = $temp;
}
// 从$arr[$i]开始向下进行堆调整
function Heapify(&$arr, $i, $heap_size)
{
$left_child = 2 * $i + 1; // 左孩子索引
$right_child = 2 * $i + 2; // 右孩子索引
$max = $i; // 选出当前结点与其左右孩子死难者之中最大值
if ($left_child < $heap_size && $arr[$left_child] > $arr[$max]) {
$max = $left_child;
}
if ($right_child < $heap_size && $arr[$right_child] > $arr[$max]) {
$max = $right_child;
}
if ($max != $i) {
Swap($arr, $i, $max); // 当前结点与最大值进行交换
Heapify($arr, $max, $heap_size); // 递归,继续调整
}
}
// 建堆,时间复杂度O(n)
function BuildHeap(&$arr, $len)
{
$heap_size = $len;
for ($i = floor($heap_size / 2) - 1; $i >= 0; $i--) { // 从每一个非叶子结点开始向下进行堆调整
Heapify($arr, $i, $heap_size);
}
return $heap_size;
}
// 堆排序
function HeapSort($arr, $len)
{
$heap_size = BuildHeap($arr, $len); // 建立最大堆(无序区)
while ($heap_size > 1) { // 堆(无序区)元素大于1,未完成排序
Swap($arr, 0, --$heap_size); // 将堆定元素沉到堆底(成为有序区),堆(无序区)-1
Heapify($arr, 0, $heap_size); // 从新的栈顶元素开始向下调整
}
return $arr;
}
print_r(HeapSort($arr, $len));