快速排序:顧名思義,這是實踐中的一種快速的排序算法,它平均運行實踐是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 )