排序:堆排序

堆: 一个完全二叉树
任何一个节点的值,都大于等于它两个子节点的值,称为大顶堆
任何一个节点的值,都小于等于它两个子节点的值,称为小顶堆

根据定义可以知道
大顶堆根节点为最大值,小顶堆的根节点为最小值

以大顶堆为例,a长度为n 下标 1~n
全部节点建大顶堆,根节点a[1]为最大值,将根节点a[1]与最后一个节点a[n]交换,a[n]为最大值
1到n-1建大顶堆,根节点a[1]为最大值,将根节点a[1]与最后一个节点a[n-1]交换,a[n-1]为次大值
...
1到n-i建大顶堆,根节点a[1]为最大值,将根节点a[1]与最后一个节点a[n-i]交换,a[n-i]为i大值
由此达到排序的作用

建堆: N/2*log(N)
调整堆: (N-1)*log(N)
总时间复杂度: Nlog(N)

//大顶堆
function head(&$a, $start, $end){
    $tmp = $a[$start];
    $left = $start*2;
    while($left<$end){
        if($left+1<=$end && $a[$left+1]>$a[$left])
            $left++;
        if($a[$left]<=$tmp)//与最初的值比较
            break;
        $a[$start] = $a[$left];//用较大的子节点替换,start下移
        $start = $left;//调整根节点
        $left = $start*2;//新的子节点
    }
    $a[$start] = $tmp;
}

//           1  2  3  4  5  6  7
$a = array(0,10,15,56,25,30,70,66);
$cnt = count($a);
$cnt1 = intval($cnt/2);

for($i=$cnt1;$i>=1;$i--){
    head($a,$i,$cnt-1);
    $tt = implode(',', $a);
    var_dump($tt);
}

$n = $cnt-1;
for($i=$n;$i>=1;$i--){
    $tmp = $[$i];//取第一个元素放置到最后
    $[$i] = $a[1];
    $a[1] = $tmp;
    head($a,1,$i-1);
}
原文地址:https://www.cnblogs.com/yyf573462811/p/6420178.html