介紹三種排序算法php
選擇排序(Selection sort)是一種簡單直觀的排序算法。它的工做原理是每一次從待排序的數據元素中選出最小(或最大)的一個元素,存放在序列的起始位置,直到所有待排序的數據元素排完。 選擇排序是不穩定的排序方法(好比序列[5, 5, 3]第一次就將第一個[5]與[3]交換,致使第一個5挪動到第二個5後面)。算法
簡單解釋
首先默認序列的第一個元素爲最小值A,而後從剩下的序列裏面,選取最小值B,若是B<A,那麼替換二者的位置。而後繼續比較第二個位置,從剩餘的隊列裏面選取最小的值放到第二個位置,以此類推數組
code性能
function selectSort($arr) { $len = count($arr); for($i = 0 ; $i < $len - 1; $i ++) { // 默認第一個是最小值 $min = $i; // 注意這裏是從$i + 1 開始遍歷剩餘的元素,選出最小值 for($n = $i + 1 ; $n < $len; $n ++) { if($arr[$n] < $arr[$min]) { $min = $n; } } // 若是最小值不是當前默認的最小值,那麼進行替換 if($min != $i) { $t = $arr[$i]; $arr[$i] = $arr[$min]; $arr[$min] = $t; } } return $arr; }
比較相鄰的元素。若是第一個比第二個大,就交換他們兩個。對每一對相鄰元素做一樣的工做從開始第一對到結尾的最後一對。在這一點,最後的元素應該會是最大的數。針對全部的元素重複以上的步驟,除了最後一個。持續每次對愈來愈少的元素重複上面的步驟,直到沒有任何一對數字須要比較。測試
簡單解釋
要比較N輪,每輪都要比較N-當前輪次的次數, 每次都會選出一個最大值放到後面(有點抽象)ui
代碼code
function bubbleSort($arr) { $len = count($arr); // 這裏比較N次 for($i = 0; $i< $len - 1; $i++) { // 每次比較實際上都要-$i,由於每次比較結束後最後一個值就不用參與下次比較了 for($n = 0; $n < $len - 1 - $i; $n ++) { if($arr[$n] > $arr[$n + 1]) { $t = $arr[$n]; $arr[$n] = $arr[$n + 1]; $arr[$n + 1] = $t; } } } return $arr; }
經過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的全部數據都比另一部分的全部數據都要小,而後再按此方法對這兩部分數據分別進行快速排序,整個排序過程能夠遞歸進行,以此達到整個數據變成有序序列。排序
簡單解釋
這個真的更抽象,由於,就是將小的放一邊,大的放一邊,而後遞歸出來遞歸
code隊列
function quickSort($arr) { $len = count($arr); // 由於是遞歸,因此若是最後的數組多是空的也多是1個,那麼就沒有可比較的了,直接返回 if($len <= 1) { return $arr; } $base = $min = $max = []; $base_item = $arr[0]; for($i = 0; $i < $len ; $i++) { if($arr[$i] < $base_item) { $min[] = $arr[$i]; }elseif($arr[$i] > $base_item) { $max[] = $arr[$i]; }else { $base[] = $arr[$i]; } } $min = quickSort($min); $max = quickSort($max); // 每次構造新的序列 return array_merge($min,$base,$max); }
這三個排序算法的時間複雜度是不同的,咱們來測試下性能。咱們用下面代碼來生成散列數組。
$arr = range(0,$argv[1]); shuffle($arr);
而後執行上面三個方法
$time = execTime(); // 快速排序 quickSort($arr); $time = execTime($time); // 選擇排序 selectSort($arr); $time = execTime($time); // 冒泡排序 bubbleSort($arr); $time = execTime($time); // 這個是計算毫秒耗時的方法 function execTime($microTime = 0) { $microTime && var_dump(microtime(true)*1000 - $microTime); return microtime(true)*1000; }
看下執行結果,果真最快的是快速排序
php sort_practice.php 10 float(0.0419921875) float(0.011962890625) float(0.011962890625) php sort_practice.php 100 float(0.30908203125) float(0.396240234375) float(0.779052734375) php sort_practice.php 200 float(0.687744140625) float(1.93994140625) float(3.37890625) php sort_practice.php 300 float(0.85400390625) float(3.222900390625) float(8.123046875) php sort_practice.php 400 float(1.23193359375) float(5.857177734375) float(11.824951171875) php sort_practice.php 500 float(1.559814453125) float(8.73291015625) float(21.15087890625) php sort_practice.php 600 float(1.70703125) float(14.300048828125) float(30.343994140625) php sort_practice.php 700 float(2.265869140625) float(18.0390625) float(41.654052734375) php sort_practice.php 800 float(2.581298828125) float(24.72998046875) float(53.56005859375) php sort_practice.php 900 float(2.682861328125) float(31.9560546875) float(65.988037109375) php sort_practice.php 1000 float(3.18701171875) float(36.010986328125) float(78.216064453125) php sort_practice.php 2000 float(6.450927734375) float(151.62475585938) float(313.64624023438) php sort_practice.php 3000 float(11.026123046875) float(362.6640625) float(721.11572265625) php sort_practice.php 4000 float(15.346923828125) float(667.11791992188) float(1314.2221679688) php sort_practice.php 5000 float(20.559814453125) float(1029.8937988281) float(2057.3466796875) php sort_practice.php 6000 float(27.767822265625) float(1534.2431640625) float(2917.7407226562) php sort_practice.php 7000 float(33.481201171875) float(2083.5861816406) float(3984.7060546875) php sort_practice.php 8000 float(38.852783203125) float(2606.0270996094) float(5157.6708984375) php sort_practice.php 9000 float(42.02587890625) float(3436.4509277344) float(6638.451171875) php sort_practice.php 10000 float(45.932861328125) float(4640.3000488281) float(8474.2751464844)
再寫一個經典搜索
先從中間開始找,遞歸相似快速排序
$arr = range(0, $argv[1]); $value = mt_rand(0, count($arr)); var_dump($value); function binSearch($value, $arr) { if(!$arr) { return false; } $sign = floor(count($arr)/2); $middle = $arr[$sign]; if($middle == $value) { var_dump($middle); }else { binSearch($value,array_slice($arr, 0, $sign)); binSearch($value,array_slice($arr, $sign + 1)); } } binSearch($value,$arr);