php实现快速排序算法

272 阅读1分钟

理解

每次排序的时候设置一个基准点,将小于等于基准点的数全部放到基准点的左边,将大于等于基准点的数全部放到基准点的右边。这样在每次交换的时候就不会像冒泡排序一样只能在相邻的数之间进行交换,交换的距离就大得多了。因此总的比较和交换次数就少了,速度自然就提高了。当然在最坏的情况下,仍可能是相邻的两个数进行了交换。因此快速排序的最差时间复杂度和冒泡排序是一样的,都是 O(N2),它的平均时间复杂度为 O (NlogN)。其实快速排序是基于一种叫做“二分”的思想。不稳定排序

代码实现

单边循环法

这种代码相比双边来说简单一些,效果是一样的。

  function fast_sort_single(&$array, $start, $end)
    {
        if ($start > $end) {
            return;
        }
        $pivot = $array[$start];     //基数值
        $mark  = $start;             //左边哨兵$left

        for ($i = $start + 1; $i <= $end; $i++) {
            if ($array[$i] < $pivot) {
                $mark++;
                $temp         = $array[$mark];
                $array[$mark] = $array[$i];
                $array[$i]    = $temp;
            }
        }
        $array[$start] = $array[$mark];
        $array[$mark]  = $pivot;
        //执行下一趟快速排序
        fast_sort_single($array, $start, $mark - 1);
        fast_sort_single($array, $mark + 1, $end);
    }

双边循环法

function fast_sort_double(&$array, $i, $j)
    {
        if ($i > $j) {
            return;
        }
        $key   = $array[$i]; //基数值
        $left  = $i;         //左边哨兵$left
        $right = $j;        //右边哨兵$right

        while ($i != $j) {
            //往左边找第一个小于$key的值,直到找到
            while ($array[$j] >= $key && $i < $j) {
                $j--;
            }
            //往右边找第一个大于$key的值,直到找到
            while ($array[$i] <= $key && $i < $j) {
                $i++;
            }
            //两个都找到了,交换呗
            if ($i < $j) {
                $temp      = $array[$i];
                $array[$i] = $array[$j];
                $array[$j] = $temp;
            }
        }
        //执行下一趟快速排序
        $array[$left] = $array[$i];
        $array[$i]     = $key;
        fast_sort_double($array, $left, $i - 1);
        fast_sort_double($array, $i + 1, $right);
    }