快速排序:顾名思义,这是实践中的一种快速的排序算法,它平均运行实践是O(N log N).该算法之所以特别快,主要是由于非常精炼和高度优化的内部循环。它的最坏情形性能为O(N^2)。
像归并排序一样,快速排序也是一种分治的递归算法。
步骤:
1、从数列中挑出一个元素,称为"基准"(pivot)
2、重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(相同的数可以到任何一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
3、递归地把小于基准值元素的子数列和大于基准值元素的子数列排序。
下面我写了两种实现方法:
1、基于临时数组
每次递归都会创建两个临时数组用于存放比基准值大和比基准值小的元素,没有涉及到元素交换
2、基于元素交换
方法一:
1 /** 2 * @param $arr 要排序的数组 3 * @return array 排好序的数组 4 */ 5 function quick_sort($arr) 6 { 7 $count = count($arr); 8 if ($count < 2) { 9 return $arr; 10 } 11 //创建临时数组,以基准值为分界线,大于基准值的放在右侧,小鱼基准值的放在左侧 12 $leftArr = $rightArr = array(); 13 //基准值,一般取数组第一个元素 14 $middle = $arr[0]; 15 //循环数组与基准值比较 16 for ($i = 1; $i < $count; $i++) { 17 if ($arr[$i] < $middle) { 18 $leftArr[] = $arr[$i]; 19 } else { 20 $rightArr[] = $arr[$i]; 21 } 22 } 23 //递归,将左右数组排序 24 $leftArr = quick_sort($leftArr); 25 $rightArr = quick_sort($rightArr); 26 27 //将排好序的临时数组合并 28 return array_merge($leftArr, array($middle), $rightArr); 29 30 }
方法二:
1 /** 2 * @param $arr 要排序的数组 3 * @return array 排好序的数组 4 */ 5 function quickSort($arr) 6 { 7 $count = count($arr); 8 if ($count < 2) { 9 return $arr; 10 } 11 12 $i = 0; 13 $j = $count - 1; 14 //基准值 15 $key = $arr[0]; 16 while ($i < $j) { 17 //首先从后往前比较,比基准值大的放过,比基准值小的做交换 18 while ($i < $j && $arr[$j] >= $key) { 19 $j--; 20 } 21 //交换 22 $arr[$i] = $arr[$j]; 23 $arr[$j] = $key; 24 //再从前往后比较,比基准值小的放过,比基准值大的做交换 25 while ($i < $j && $arr[$i] <= $key) { 26 $i++; 27 } 28 $arr[$j] = $arr[$i]; 29 $arr[$i] = $key; 30 31 } 32 //经过一轮交换,基准值左侧全部比基准值小,基准值右侧全部比基准值大,但左右两侧并不一定是排好序的 33 //然后进行递归,将基准值左右两侧进行排序 34 if ($i == 0) { 35 $l = []; 36 } else { 37 $l = quickSort(array_slice($arr, 0, $i)); 38 } 39 40 if ($i == $count - 1) { 41 $r = []; 42 } else { 43 $r = quickSort(array_slice($arr, $i + 1, $count + 1 - $i)); 44 } 45 //将排好序的数组进行合并返回 46 return array_merge($l, array($key), $r); 47 }
测试:
1 $arr = [1, 0, 8, 3, 4, -2, -6, 7, -10]; 2 $sortArr = quick_sort($arr); 3 print_r($sortArr); 4 echo '<br>'; 5 $sortArr1 = quickSort($arr); 6 print_r($sortArr1);
输出分别为:
Array ( [0] => -10 [1] => -6 [2] => -2 [3] => 0 [4] => 1 [5] => 3 [6] => 4 [7] => 7 [8] => 8 )
Array ( [0] => -10 [1] => -6 [2] => -2 [3] => 0 [4] => 1 [5] => 3 [6] => 4 [7] => 7 [8] => 8 )