PHP 常用例子

堆排序利用堆的特性对数组进行排序。它涉及构建一个用于递增顺序排序的最大堆,其中在根处包含堆的最大元素。对于降序排序,使用最小堆,它在根处包含堆的最小元素。堆排序的升序排序的过程步骤总结如下:

  • 第1步:构建一个最大堆,其中根部包含堆的最大元素
  • 第2步: 将堆的最后一个元素与根元素交换,并从堆中删除最后一个元素。对其余元素重复步骤 1。

示例:

要了解堆排序,让我们考虑一个未排序的数组[10, 1, 23, 50, 7, -4] 并讨论按升序对数组进行排序所采取的每个步骤。

下图中显示了输入数组和最大堆的堆结构。堆的根元素的索引号为0。在最大堆中,堆的最大元素始终位于根。

PHP程序 堆排序

构建初始最大堆后,堆的最后一个元素与根元素以及包含数组中最大的数将从堆中删除。之后,对堆中剩余的元素使用heapify函数,使其成为最大堆,元素数量将减少1。这个过程一直持续到堆中的元素数量为1。此时,数组将被排序。

PHP程序 堆排序

上图描述了从堆中消除最大元素以及从堆的剩余元素形成最大堆。该过程的最终结果是一个升序排序的数组。

堆排序的实现

<?php
// 调用heapify函数的堆排序函数
//构建最大堆,然后交换最后一个元素
// 第一个元素的最大堆
//从堆中排除最后一个元素并重建堆
function heapsort(&$Array, $n) {
  for($i = (int)($n/2); $i >= 0; $i--) {
    heapify($Array, $n-1, $i);
  }
  
  for($i = $n - 1; $i >= 0; $i--) {
    //将最大堆的最后一个元素与第一个元素交换
    $temp = $Array[$i];
    $Array[$i] = $Array[0];
    $Array[0] = $temp;

    //从堆中排除最后一个元素并重建堆
    heapify($Array, $i-1, 0);
  }
}

// heapify函数用于构建最大堆
//最大堆在根处有最大元素,这意味着
//数组的第一个元素将是最大堆中的最大值
function heapify(&$Array, $n, $i) {
  $max = $i;
  $left = 2*$i + 1;
  $right = 2*$i + 2;

  //如果左边元素大于根
  if($left <= $n && $Array[$left] > $Array[$max]) {
    $max = $left;
  }

  //如果右侧元素大于根
  if($right <= $n && $Array[$right] > $Array[$max]) {
    $max = $right;
  }

  //如果最大值不是i
  if($max != $i) {
    $temp = $Array[$i];
    $Array[$i] = $Array[$max];
    $Array[$max] = $temp;
    //递归地堆化受影响的子树
    heapify($Array, $n, $max); 
  }
}

//打印数组的函数
function PrintArray($Array, $n) { 
  for ($i = 0; $i < $n; $i++) 
    echo $Array[$i]." "; 
  echo "\n";
} 

//测试代码
$MyArray = array(10, 1, 23, 50, 7, -4);
$n = sizeof($MyArray); 
echo "原始数组\n";
PrintArray($MyArray, $n);

heapsort($MyArray, $n);
echo "\n排序数组\n";
PrintArray($MyArray, $n);
?> 

上面的代码将给出以下输出:

原始数组
10 1 23 50 7 -4 

排序数组
-4 1 7 10 23 50 

时间复杂度:

创建堆的时间复杂度为θ(N),创建最大堆的时间复杂度为θ(logN) em> 堆排序的总体时间复杂度为 θ(NlogN)