<?php
//堆的根节点为1,所以数组从1开始,0的位置用0占位,不参与排序
$arr = Array(0,2,4,5,4,9,3,2,8,7,0);
//调整堆,$i为筛选结点位置,$j为最后一个叶子结点
function sift(&$arr,$i,$j){
$child = $i*2; //左孩子
//当被筛选结点是叶子时退出循环
while($child <= $j){
if($child<$j && $arr[$child]<$arr[$child+1]){
$child++;//右孩子
}
if($arr[$i]>$arr[$child]){
break;
}else{
$key = $arr[$i];
$arr[$i] = $arr[$child];
$arr[$child] = $key;
//将被筛选节点放到孩子结点继续筛选
$i=$child;
$child = $i*2;
}
}
}
function heap(&$arr,$n){
//初始建堆,从最后一个分支结点到根节点
for ($i=$n/2; $i >=1 ; $i--) {
sift($arr,$i,$n);
}
//打印建好的堆
foreach ($arr as $key => $value) {
echo $value."\n";
}
//重复执行移走堆顶及重建堆;
for($i = 1;$i < $n; $i++){
$key = $arr[1];
$arr[1] = $arr[$n-$i+1];
$arr[$n-$i+1] = $key;
sift($arr,1,$n-$i);
}
}
heap($arr,count($arr)-1);
echo "</br>";
foreach ($arr as $key => $value) {
echo $value."\n";
}