堆: 一个完全二叉树
任何一个节点的值,都大于等于它两个子节点的值,称为大顶堆
任何一个节点的值,都小于等于它两个子节点的值,称为小顶堆
根据定义可以知道
大顶堆根节点为最大值,小顶堆的根节点为最小值
以大顶堆为例,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); }