php幾種常用演算法
阿新 • • 發佈:2019-02-05
寫一下幾種常見排序演算法,清一下腦子
歸併排序
/**
* Created by PhpStorm.
* User: leon
* Date: 2018/3/14
* Time: 下午2:37
*/
function mergeSort(&$arr) {
$len = count($arr);//求得陣列長度
mSort($arr, 0, $len-1);
return $arr;
}
//實際實現歸併排序的程式
function mSort(&$arr, $left, $right) {
if($left < $right) {
//說明子序列記憶體在多餘1個的元素,那麼需要拆分,分別排序,合併
//計算拆分的位置,長度/2 去整
$center = floor(($left+$right) / 2);
//遞迴呼叫對左邊進行再次排序:
mSort($arr, $left, $center);
//遞迴呼叫對右邊進行再次排序
mSort($arr, $center+1, $right);
//合併排序結果
mergeArray($arr, $left, $center, $right);
}
}
//將兩個有序數組合併成一個有序陣列
function mergeArray(&$arr , $left, $center, $right) {
//設定兩個起始位置標記
$a_i = $left;
$b_i = $center+1;
while($a_i<=$center && $b_i<=$right) {
//當陣列A和陣列B都沒有越界時
if($arr[$a_i] < $arr[$b_i]) {
$temp[] = $arr[$a_i++];
} else {
$temp[] = $arr[$b_i++];
}
}
//判斷 陣列A內的元素是否都用完了,沒有的話將其全部插入到C陣列內:
while($a_i <= $center) {
$temp[] = $arr[$a_i++];
}
//判斷 陣列B內的元素是否都用完了,沒有的話將其全部插入到C陣列內:
while($b_i <= $right) {
$temp[] = $arr[$b_i++];
}
//將$arrC內排序好的部分,寫入到$arr內:
for($i=0, $len=count($temp); $i<$len; $i++) {
$arr[$left+$i] = $temp[$i];
}
}
$SortArr = array(2,9,1,8,3,8);
$res = mergeSort($SortArr);
print_r($res);
選擇排序
/**
* Created by PhpStorm.
* User: leon
* Date: 2018/3/13
* Time: 下午6:44
*/
/*
* 思路:
* 每一次從待排序的資料元素中選出最小(或最大)的一個元素,存放在序列的起始位置,直到全部待排序的資料元素排完。
* 選擇排序是不穩定的排序方法(比如序列[5, 5, 3]第一次就將第一個[5]與[3]交換,導致第一個5挪動到第二個5後面)
*/
function selectSort(...$array){
$temp = 0;
for($i = 0;$i < count($array) - 1;$i++){
$minVal = $array[$i]; //假設$i就是最小值
$minValIndex = $i;
for($j = $i+1;$j < count($array);$j++){
if($minVal > $array[$j]){ //從小到大排列
$minVal = $array[$j]; //找最小值
$minValIndex = $j;
}
}
$temp = $array[$i];
$array[$i] = $array[$minValIndex];
$array[$minValIndex] = $temp;
print_r($array);
}
return $array;
}
$res = selectSort(2,9,1,8,3,8);
var_dump($res);
插入排序
/**
* Created by PhpStorm.
* User: leon
* Date: 2018/3/13
* Time: 下午6:27
*/
/**
* @param array ...$args
* @return array
* 從元素 1 開始作為插入數字 , i-1 和 i 比,換i和 i-1 位,while 再把i-2和 i-1 新的insertValue比
* 直到不滿足while,或者到頭 ,還需要比一下index+1是否等於當前迴圈次數,
* 來判斷是否迴圈超過1次,這樣可以把最左邊用insert補全
*/
function InsertSort(...$args){
print_r($args);
for ($i = 1;$i < count($args); $i++){
$insertVal = $args[$i]; //$insertVal是準備插入的數
var_dump($i);
var_dump('準備插入:'.$insertVal);
print_r('while之前');
print_r($args);
$insertIndex = $i - 1; //1
while( $insertIndex >= 0 && $insertVal < $args[$insertIndex] ){
var_dump('進入while');
$args[$insertIndex + 1] = $args[$insertIndex]; //將陣列往後挪
$insertIndex--;
}
var_dump('while之後');
print_r($args);
if($insertIndex + 1 !== $i){//迴圈 > 1次時,會觸發,將插入值,放在最前面
$args[$insertIndex + 1] = $insertVal;
}
var_dump('if之後');
print_r($args);
}
return $args;
}
(InsertSort(2,9,1,8,3,8,3,2,2));
快速排序
/**
* Created by PhpStorm.
* User: leon
* Date: 2018/3/13
* Time: 下午4:51
*/
function QuickSort($args){
//這裡要加一個限制,不然無限遞迴了
if (!isset($args[1])) return $args;
$mid = $args[0];//分割關鍵詞 。小的放一個 大的放一個
$leftArr = array();
$rightArr = array();
foreach ($args as $value){
if ($value > $mid) $rightArr[] = $value;
if ($value < $mid) $leftArr[] = $value;
}
$leftArr = QuickSort($leftArr);
$leftArr[] = $mid;
$rightArr = QuickSort($rightArr);
return array_merge($leftArr,$rightArr);
}
$rt = array(6,3,2,8,11,1);
print_r(QuickSort($rt));
///*
//* 思路:
//* 通過一趟排序將要排序的資料分割成獨立的兩部分,其中一部分的所有資料都比另外一部分的所有資料都要小,
//* 然後再按此方法對這兩部分資料分別進行快速排序,整個排序過程可以遞迴進行,以此達到整個資料變成有序序列。
//* */
//function quickSort1($array){
// if(!isset($array[1])) return $array;
// $mid = $array[0]; //獲取一個用於分割的關鍵字,一般是首個元素
// $leftArray = array();
// $rightArray = array();
// foreach($array as $v){
// if($v > $mid)
// $rightArray[] = $v; //把比$mid大的數放到一個數組裡
// if($v < $mid)
// $leftArray[] = $v; //把比$mid小的數放到另一個數組裡
// }
// $leftArray = quickSort($leftArray); //把比較小的陣列再一次進行分割
// $leftArray[] = $mid; //把分割的元素加到小的陣列後面,不能忘了它哦
// $rightArray = quickSort($rightArray); //把比較大的陣列再一次進行分割
// return array_merge($leftArray,$rightArray); //組合兩個結果
//}
//$arr= array(6,3,8,2,9,1);
//$res = quickSort($arr);
//var_dump($res);
氣泡排序
/**
* Created by PhpStorm.
* User: leon
* Date: 2018/3/13
* Time: 下午4:06
*/
function BubbleSort(...$args){
$count = count($args);
$temp = 0;
//外層控制排序輪次
for ($i = 0; $i < $count-1;$i++ ){
//內層控制每輪比較次數
for ($j = 0;$j < $count-$i-1;$j++){
if ($args[$j] > $args[$j+1]){
$temp = $args[$j];
$args[$j] = $args[$j+1];
$args[$j+1] = $temp;
}
}
}
return $args;
}
print_r(BubbleSort(2323,22,2,3,5,4,2,3));
總結:
1. 插入排序:穩定,O(n2)
2. 氣泡排序:穩定,O(n2) 一次長度減少1
3. 快排:不穩定。O(nlogn)最差 o(n2) ,二分排序,查詢減半
4. 選擇排序:不穩定:O(n2)
5. 歸併排序:O(n log n)