PHP常用排序演算法01——冒泡、插入
阿新 • • 發佈:2021-01-20
技術標籤:演算法和資料結構PHP後端演算法排序演算法php資料結構插入排序
對於排序演算法,相信學計算機的同學都不會陌生。今天我們就來複習下常見的兩個排序,適合小規模資料的排序演算法:冒泡(bubbleSort)和插入(insertionSort)。
PS:對排序等演算法還不太瞭解的同學,可以去看下這個連結哦,十大經典排序演算法(動圖演示),一些基礎定義和動圖演示做的很好啦,程式碼是用JavaScript實現的。我這個呢是PHP版本,而且有些小細節優化會註明在程式碼段上,都是經過本人實際操作的,下面開始正文。
1、氣泡排序
(1)概念:
①依次比較相鄰的兩個資料,大小關係不對,就互換位置;
(2)優化:當某次冒泡操作已經沒有資料交換時,說明已經達到完全有序,不用再繼續執行後續的冒泡操作。
(3)程式碼實現如下:
public static function bubbleSort(){
$array = [4,5,6,3,2,1];
$count = count($array);
//外層迴圈控制冒泡出去的個數,冒一個需要一個個去比較一輪
for($i=0;$i<$count;$i++){
$flag = false; //提前退出冒泡迴圈的標誌位。當不需要再比較的時候,就會停止迴圈了。該處是優化程式碼
for($j=0;$j<$count-$i-1;$j++){ //內層迴圈控制每一輪需要比較的次數。比如,冒出一個了,每輪就少比較一個數。冒出兩個了,每輪就少比較兩個數
if($array[$j] > $array[$j+1]){
$temp = $array[$j];
$array[$j] = $array[$j+1];
$array[$j+1] = $temp;
$flag = true; //內層迴圈但凡比較了一次,$flag = true 就會執行,下一輪外層就會繼續迴圈。該處是優化程式碼
}
}
if(!$flag){break;}//內層迴圈但凡比較了一次,$flag = true 就會執行,下一輪外層就會繼續迴圈。該處是優化程式碼
}
return $array;
}
2、插入排序
(1)概念:
①將陣列中的資料分為兩個區間,已排序區間和未排序區間。
②初始已排序區間只有一個元素,就是陣列的第一個元素。
③取未排序區間中的元素,在已排序區間中找到合適的插入位置將其插入,並保證已排序區間資料一直有序。重複這個過程,直到未排序區間中元素為空,演算法結束。
(2)程式碼實現如下:
public static function insertionSort()
{
$array = [4,5,6,1,3,2];
$count = count($array); //分為已排序和未排序的。未排序的往已排序好的找準位置插入
for($i=1;$i < $count;$i++){ //從第二個元素開始(未排序)往已排序的那塊插入
$value = $array[$i]; //未排序的,要排序的值
$j = $i - 1; //未排序的前一個,即已排序的第一個下標
//查詢插入的位置
for($j;$j >= 0;$j--){ //從已排序的第一個下標開始,一個個遍歷對比未排序的
if($array[$j] > $value){
$array[$j+1] = $array[$j]; //大小關係沒按順序排時,對比依次往後挪一個下標空間。騰出空間讓新元素插入
}else{ //因為左邊是已經排好序的了,所以位置對了就可以跳出迴圈了
break;
}
}
$array[$j+1] = $value; //插入資料
}
return $array;
}
3、冒泡和插入的比較
(1)氣泡排序和插入排序的時間複雜度都是 O(n2),都是原地排序演算法(排序時不需要額外的儲存空間),都是穩定的排序演算法,空間複雜度均為O(1),比較適用於小規模的資料排序(至於大規模的資料排序,那就要用到快速排序、歸併排序、堆排序之類的啦);
(2)但插入排序更受歡迎,因為從程式碼實現上來看,氣泡排序的資料交換要比插入排序的資料移動要複雜。如下圖所示,很明顯冒泡交換移動操作更多,更耗時。
圖一:冒泡的資料交換操作
圖二:插入的資料交換操作