1. 概述

  • 思路:数组排序中,选取数组末尾的一个数叫作轴,初始一左一右指针分别都往序列中间位置逐步移动,比轴小的不动,比轴大的数与轴往前的位置的数交换值,完成后让轴与右指针交换位置,这样就完成了一次大小数字以轴为界限分成两部分了。再对当前序进行递归二分至1个元素,完成完成上述排序过程。
  • 稳定性:不稳定(在一次排序中,可能出现左边的大数(存在相同指)交换到相同值的右边去,比如序列:[1834825] -> [1234885],在交换$arr[1]和$arr[5]时,对于原序,前面的8跑到右边的8的后面去了)
  • 优化:1. 随机选择一个数与末尾数交换(这样可以减少原序已经是顺序的情况,因为顺序的时候时间复杂度最大)2. 双轴快排

    2. 实现代码

    ```php <?php class QuickSort { private array $ori = []; public array $new = []; public function __construct(array $arr) {

    1. $this->ori = $arr;
    2. $r = $this->sort($this->ori, 0, count($arr) - 1);
    3. $this->new = $r;

    }

    private function sort(array $arr, int $lBd, int $rBd) {

      if ($lBd >= $rBd) return $arr;
    
      list($arr, $mid) = $this->partition($arr, $lBd, $rBd);
      $arr = $this->sort($arr, $lBd, $mid - 1);
      $arr = $this->sort($arr, $mid + 1, $rBd);
      return $arr;
    

    }

    private function partition($arr, $lBd, $rBd) {

      $pivot = $arr[$rBd];
      $left = $lBd;
      $right = $rBd - 1;
    
      // 防止最差情况(最差的时间复杂度是n^2)
      if ($right > $left + 1) {
          self::swap($arr, $right, floor(($right - $left) / 2) + 1);
      }
    
      while($left <= $right) {
          while ($left <= $right && $arr[$left] <= $pivot) $left++;
          while ($left <= $right && $arr[$right] > $pivot) $right--;
          if ($left < $right) {
              $arr = self::swap($arr, $left, $right);
          }
      }
      $arr = self::swap($arr, $left, $rBd);
      return [$arr, $left];
    

    }

    public static function swap(array $arr, int $i, int $j) {

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

    } }

$arr = [9, 6, 11, 3, 5, 12, 8, 7, 10, 15, 14, 4, 1, 13, 2]; $cls = new QuickSort($arr); echo implode(‘,’, $cls->new); ```