堆的定义:
堆排序:基本思路,将待排序的一维数组看成是一个完全二叉树,将其生成一个堆,由定义可知,根元素必定是最小值(或最大值),将根输出,然后将剩余元素再调整成堆。
生成堆的方法:将序列看成一棵完全二叉树,从最后一个非终端结点[n/2]开始,将该点与它的左右子树根结点比较,将最小的移动到该结点位置,一直将该结点移动到使该子树符合堆定义为止,一直遍历到序列第1个结点,就构造好了一个堆。
调整堆的方法:如下图,如果将13输出,然后将序列中最后一个值97移到第一位,可知,破坏了堆的结构,需要调整,判断左右子树根节点,取值小的27与97互换,可知右子树对结构被破坏,用同样的方法进行调整,
代码实现:
/**
* @name 数组排序堆排序
* @use 使用堆排序算法将数组进行排序,数组类型为每个元素都含有“value”属性用于排序
* @param arr 数组
* @param height 待排序段的最高下标
*/
public static function sortStack(&$arr)
{
$arr[] = $arr[0];
unset($arr[0]);
self::createStack($arr);
$num = count($arr);
for ($i = $num; $i > 1; $i--) {
$temp = $arr[$i];
$arr[$i] = $arr[1];
$arr[1] = $temp;
self::adjustStack($arr, 1, $i - 1);
}
}
public static function adjustStack(&$arr, $index, $height) {
$leftChild = 2 * $index;
$rightChild = 2 * $index + 1;
$temp = $arr[$index];
if ($leftChild > $height) {
return ;
}
if ($rightChild > $height) {
if ($arr[$leftChild]['value'] < $arr[$index]['value']) {
$arr[$index] = $arr[$leftChild];
$arr[$leftChild] = $temp;
}
return ;
}
if ($arr[$leftChild]['value'] <= $arr[$rightChild]['value'] && $arr[$leftChild]['value'] < $arr[$index]['value']) {
$arr[$index] = $arr[$leftChild];
$arr[$leftChild] = $temp;
self::adjustStack($arr, $leftChild, $height);
} else if ($arr[$leftChild]['value'] > $arr[$rightChild]['value'] && $arr[$rightChild]['value'] < $arr[$index]['value']) {
$arr[$index] = $arr[$rightChild];
$arr[$rightChild] = $temp;
self::adjustStack($arr, $rightChild, $height);
}
}
public static function createStack(&$arr) {
for ($i = floor(count($arr) / 2); $i > 0; $i--) {
self::adjustStack($arr, $i, count($arr));
}
}