美文网首页
时间复杂度为o(nlogn)的排序

时间复杂度为o(nlogn)的排序

作者: bigFaceMm | 来源:发表于2019-10-18 16:19 被阅读0次

    /**

    * 不断地从中间切分

    * 归并排序,可以保证在合并前后相同值得元素的先后顺序不变

    * 时间复杂度为O(nlogn)

    * 时间复杂度是稳定的

    * 空间复杂度为O(N)

    * @param $arr

    * @param $n

    * @return array

    */

    function merge_sort($arr, $n)

    {

        return merge_sort_c($arr, 0, $n-1);

    }

    function merge_sort_c($arr, $l, $r)

    {

        if ($l >= $r) {

            return [$arr[$r]];

        }

        $p = (int)(($l+$r)/2);

        $left  = merge_sort_c($arr, $l, $p);

        $right = merge_sort_c($arr, $p+1, $r);

        $merger  = merger($left, $right);

        return $merger;

    }

    function merger($l, $r)

    {

        $tmp = [];

        $lengthLeft = count($l);

        $lengthRight = count($r);

        $i=$j=0;

        do {

            if ($l[$i] > $r[$j]) {

                $tmp[] = $r[$j++];

            } else {

                $tmp[] = $l[$i++];

            }

        } while($i<$lengthLeft && $j<$lengthRight);

        if ($i < $lengthLeft) {

            $start = $i;

            do{

                $tmp[] = $l[$start++];

            } while ($start < $lengthLeft);

        }

        if ($j < $lengthRight) {

            $start = $j;

            do{

                $tmp[] = $r[$start++];

            } while ($start < $lengthRight);

        }

        return $tmp;

    }

    /**

    * 快速排序

    * 需要寻找分区点,将数组切分成三部分,小于分区点,分区点,大于分区点

    * 原地不稳定

    * 时间复杂度O(nlogn) 极端情况下,复杂度会变成O(n^2)

    *

    *

    */

    function quick_sort(&$arr)

    {

        $n = count($arr);

        if ($n <= 1) {

            return;

        }

        quick_fort_c($arr, 0, $n-1);

    }

    function quick_fort_c(&$arr, $p, $r)

    {

        if ($p >= $r) {

            return;

        }

        $m = partition($arr, $p, $r);

        quick_fort_c($arr, $p, $m-1);

        quick_fort_c($arr, $m+1, $r);

    }

    function partition(&$arr, $p, $r)

    {

        $privot = $arr[$r];

        $i = $p;

        for ($j=$p; $j<$r-1;$j++) {

            if ($arr[$j] < $privot) {

              $tmp = $arr[$j];

              $arr[$j] = $arr[$i];

              $arr[$i] = $tmp;

            }

            $i++;

        }

        $tmp = $arr[$r];

        $arr[$r] = $arr[$i];

        $arr[$i] = $tmp;

        return $i;

    }

    相关文章

      网友评论

          本文标题:时间复杂度为o(nlogn)的排序

          本文链接:https://www.haomeiwen.com/subject/tjpgyctx.html