<?php
/* 共需要三个函数:
下标从0开始所以左右子节点分别为:2*$i+1,2*$i+2。
heapify() 调整堆,调整第$i个非叶子节点,将其调整到合适的位置。
1:比较$i和左右子节点的值,$max为最大值的下标,将最大的调整父节点。
2:递归调用,将$i放置到正确的位置。
buildheap() 建立堆。从最后一个非叶子节点开始,向根节点循环,$i--。
heapsort() 排序。先建立堆,然后把堆的第一个元素和最后一个交换,再调整堆,
此时最后一个元素一定是最大值,
*/
function heapify(&$arr,$i,$len){//作用:把$i的值放到合适的位置
$left = 2*$i+1;
$right = 2*$i+2;
$max = $i; //***$max 为中间变量用来标记最大值的下标
if($left<$len&&$arr[$max]<$arr[$left]){
$max = $left;
}
if($right<$len&&$arr[$max]<$arr[$right]){
$max = $right;
}
//此时三个值中最大值的下标为max。
//$i所处原本的位置不是合适的位置的情况下,和最大值交换,然后递归,接着判断现在的位置是不是合适位置。
if($max!=$i){
//把$i的值和$max的值交换,$max的值是转换后的值,
list($arr[$i],$arr[$max])=[$arr[$max],$arr[$i]];
heapify($arr,$max,$len);
}
}
function buildheap(&$arr,$len){//建立堆
$size = $len;
//$i 从最后一个非叶子节点开始。
for($i = floor($size/2)-1;$i>=0;$i--){
heapify($arr,$i,$size);
}
return $size;
}
function heapsort(&$arr,$len){
$size = buildheap($arr,$len);
while($size>1){//每循环一次得到剩余元素的最大值,
list($arr[0],$arr[$size-1])=[$arr[$size-1],$arr[0]];//此时最后一个元素是最大值。
heapify($arr,0,$size-1);//将$size-1个元素调整成堆。
$size--;//长度减一, 最后一个元素是最大值了 不参与下次堆排序,$arr长度不变,
}
}
$arr = [1,2,3,4,5,6,7];
heapsort($arr,7);
echo '<pre>';
print_r($arr);
PHP-排序-堆排序
最新推荐文章于 2021-05-14 22:28:47 发布