PHP实现 堆

<?php
/**
 * Created by PhpStorm.
 * User: baimayou
 * Date: 19-3-24
 * Time: 下午6:29
 * 堆:
 * 堆是一个完全二叉树;
 * 堆中每一个节点的值都必须大于等于(或小于等于)其子树中每个节点的值。
 *  堆是由数组组成,且从1开始
 */
//建立堆,向堆中插入元素(从下向上堆化)
function buildHeap(&$arr,$value){
    if(is_null($arr)){
        $arr[0] = null;
        $arr[1] = $value;
    }
    $num = count($arr);
    $arr[$num] = $value;
    $j = $num;
    $i = $j>>1;
    while($value > $arr[$i] && $i>=1){
        temp($arr,$i,$j);
        $j = $i;
        $i = $j>>1;
    }
}
//删除堆顶元素(将堆中的最后一个元素与堆顶元素交换位置,然后从上向下堆化)
function deleteHeap(&$arr){
    if(is_null($arr)){
        return false;
    }
    $num = count($arr);
    $arr[1] = $arr[$num - 1];
    unset($arr[$num-1]);
    $value = $arr[1];
    $i = 1;
    $j = $i * 2;
    while($value < $arr[$j] && $j<$num-1){
        temp($arr,$i,$j);
        $i = $j;
        $j = $i * 2;
    }

}
/*
 基于堆进行排序
  1,建堆:根据数组建堆
      ①从上向下堆化:和建堆的方法类似,将数组中的元素依次插入堆中
      ②从下向上堆化:从数组的 n/2 开始,调整此子树根节点和子节点的位置,是最大值成为根节点;聪明和n/2到1,且每次要调整以该节点为根的整棵树
  2,排序
    堆顶一定是最大或者最小的元素,所以从依次取出堆顶的元素,并调整堆即可
 * */
function sortHeap(&$arr){
    //建堆
    $num = count($arr);
    $p = floor($num/2);
    while($p >= 1){
        $i = $p;
        $j = $p * 2;
        while($j <= $num){
            if(isset($arr[$j+1]) && $arr[$j+1] > $arr[$j] && $arr[$i] < $arr[$j+1]){
                temp($arr,$i,$j+1);
            }elseif($arr[$i] < $arr[$j]){
                temp($arr,$i,$j);
            }
            $i = $j;
            $j = $j*2;
        }
        $p--;
    }
    //排序
    $resArr = [];
    for($m = $num-1;$m>0;$m--){
        $resArr[$m] = $arr[1];

        $arr[1] = $arr[$m];
        unset($arr[$m]);
        $i = 1;
        $j = $i * 2;
        //比较左右两侧的元素,选出最大值交换位置
        while($arr[$i] < ($arr[$j+1]>$arr[$j] ? $arr[$j+1] : $arr[$j]) && $j<=$num-1){
            $n = $arr[$j+1]>$arr[$j] ? $j+1 : $j;
            temp($arr,$i,$n);
            $i = $n;
            $j = $i * 2;
        }
    }
    $arr = $resArr;
}
function temp(&$arr,$i,$j){
    $temp = $arr[$i];
    $arr[$i] = $arr[$j];
    $arr[$j] = $temp;
}
$arr = [null,9,8,100,80,107,36,5,3,4,7,6];
//buildHeap($arr,100);
//var_dump($arr);
//deleteHeap($arr);
sortHeap($arr);
var_dump($arr);

上一篇:AI业务强劲增长,百度迎来了“推卒过河”的纵横时刻


下一篇:leetcode之350两个数组的交集Golang