PHP-排序-堆排序

 
    /*  共需要三个函数:
        下标从0开始所以左右子节点分别为:2*$i+1,2*$i+2。
        heapify() 调整堆,调整第$i个非叶子节点,将其调整到合适的位置。
           1:比较$i和左右子节点的值,$max为最大值的下标,将最大的调整父节点。
           2:递归调用,将$i放置到正确的位置。 
        buildheap() 建立堆。从最后一个非叶子节点开始,向根节点循环,$i--。
        heapsort() 排序。先建立堆,然后把堆的第一个元素和最后一个交换,再调整堆,
           此时最后一个元素一定是最大值,
    */
    function heapify(&$arr,$i,$len){//作用:把$i的值放到合适的位置

        $left = 2*$i+1;           
        $right = 2*$i+2;
        $max = $i;     //***$max 为中间变量用来标记最大值的下标
        if($left<$len&&$arr[$max]<$arr[$left]){
            $max = $left;
        }
        if($right<$len&&$arr[$max]<$arr[$right]){
            $max = $right;
        }
        //此时三个值中最大值的下标为max。
        //$i所处原本的位置不是合适的位置的情况下,和最大值交换,然后递归,接着判断现在的位置是不是合适位置。
        if($max!=$i){     
            //把$i的值和$max的值交换,$max的值是转换后的值,
            list($arr[$i],$arr[$max])=[$arr[$max],$arr[$i]];
            heapify($arr,$max,$len);
        }
    }

    function buildheap(&$arr,$len){//建立堆
        $size = $len;
        //$i 从最后一个非叶子节点开始。
        for($i = floor($size/2)-1;$i>=0;$i--){
            heapify($arr,$i,$size);
        }
        return $size;
    }

    function heapsort(&$arr,$len){
        $size = buildheap($arr,$len);
        while($size>1){//每循环一次得到剩余元素的最大值,
            list($arr[0],$arr[$size-1])=[$arr[$size-1],$arr[0]];//此时最后一个元素是最大值。
            heapify($arr,0,$size-1);//将$size-1个元素调整成堆。           
            $size--;//长度减一, 最后一个元素是最大值了 不参与下次堆排序,$arr长度不变,
        }

    }

    $arr = [1,2,3,4,5,6,7];
    heapsort($arr,7);
    echo '
';
    print_r($arr); 

你可能感兴趣的:(PHP)