常用的排序演算法(五)--選擇排序以及最佳化(PHP實現)
常用的排序演算法系列
選擇排序以及最佳化
選擇排序也是一種常用的簡單的排序演算法,雖然演算法的複雜度是和冒泡一樣都是O(n^2),但效能還是稍微好一些的,在一些簡單的場景中選擇排序非常好用。
假設當前需要進行排序,選擇排序的核心思路是,找到一個最大或者最小的標記位,將其與當前需要排序的位置交換他們的值,這樣的交換就會比冒泡更加有效率。
舉例說明:
假設當前需要排序的陣列如下:
[ 34, 5, 555,14, 88, 5 ]
首先我們要用一個迴圈來遍歷這個陣列,用來做排序的位置交換。
預設呢,假設當前取到的第一個數字是最小的,我們記錄下編號即可,後面找到真正的最小值編號我們再更新即可。
第一次我們取第一個數 34 作為當前的最小值,記錄下他的 最小值編號 0。
接著,我們要再用一個迴圈,去找陣列後面部分的需要交換的位置(也就是找到真正的最小值編號),當前排序的,是編號0位置,因此我們從編號1開始往後找,如果發現後面有小於等於編號位置的值,我們就更新這個最小值編號。
往後找,發現 5 比 34 小,於是最小值編號就變成了1 。
繼續往後找,發現編號5的5等於當前最小值5,於是最小值編號就變成了5 。
最後,我們來判斷一下最小值編號和最開始有沒有變化,如果有變化,說明找到了一個更小的數再後面,那就應該進行交換操作把它弄到前面來。如果沒有變化,就是說後面沒有更小的了,我們不需要交換了。往後開始排下一個位置即可。
此時最小值編號是5,已經不等於最開始我需要排序的位置0了,所以我們進行一個交換,得到的結果為:
[ 34, 5, 555,14, 88, 5 ] --> 排序一次後–> [ 5, 5, 555,14, 88, 34 ]
完成之後,我們排下一個位置,也就是位置編號1,重複上面的步驟即可。
位置1的5,找不到更小的,不理
[ 5,5, 555,14, 88, 34 ]
位置2的555,與位置5的34交換
[ 5, 5, 555,14, 88, 34 ] --> [ 5, 5, 34 ,14, 88, 555 ]
位置3的14,找不到更小的,不理
[ 5, 5, 34 ,14, 88, 555 ]
位置4的88,找不到更小的,不理
[ 5, 5, 34 ,14, 88, 555 ]
位置5的555,找不到更小的。不理
[ 5, 5, 34 ,14, 88,** 555** ]
這樣我們就完成了排序的過程。寫程式的時候要特別注意這個編號的概念,我們的目的是為了找編號,然後將對應標號的值去做交換,並不是直接去用這個最小值。
PHP實現排序過程如下:
最佳化
可以看出,我們透過找最小值的下標編號,來減少中間不必要的陣列元素交換操作,而我們每次只是標記一個最小的值,透過一個方向來排序。
因為最大最小其實是一個對稱的操作判斷,有沒有方式可以更快完成這個流程呢?
當然是有的,我們可以把原來單路的選擇排序,改成雙路的,每次標記一個最小和一個最大的值,透過兩個方向來排序。
每次排序的進行兩個標記,一個是找出範圍裡的最大值,另一個是找出範圍裡的最小值,相當於是同時在做一個兩個方向的排序,每次排序能穩定的排出來兩個值。
下一次迴圈的時候,縮減查詢的排序範圍,左邊界的值加一,右邊界的值減一,直到相遇。
這裡其實就有一點點快排的味道出來了,快排是有分治思想在裡面的,所以會更加快。
PHP排序過程如下:
程式碼
PHP選擇排序
<?php
/**
* Created by PhpStorm.
* User: L
* Date: 2018-9-27
* Time: 11:29
*/
$ar = [5, 8, 6, 4, 12, 5, 3, 1, 89, 54];
echo "input: <br/>";
print_r(json_encode($ar));
echo "<br/>";
selection($ar);
echo "result: <br/>";
print_r(json_encode($ar));
echo "<br/>";
/** 選擇排序
* @param array $ar
* @param null $len
*/
function selection(array & $ar, $len = null)
{
if ($len === null) {
$len = sizeof($ar);
}
for ($i = 0; $i < $len - 1; $i++) {
$min = $i; //consider i as min_index
for ($j = $i + 1; $j < $len; $j++) {//find min_index
if($ar[$j]<=$ar[$min]){
$min = $j;
}
}
//check min_index and swap
if($min!=$i){//changeSelectionSort.php
$t = $ar[$i];
$ar[$i]=$ar[$min];
$ar[$min] = $t;
}
echo "after 1 times: <br/>";
print_r(json_encode($ar));
echo "<br/>";
}
}
PHP選擇排序-雙路最佳化
<?php
/**
* Created by PhpStorm.
* User: L
* Date: 2018-9-27
* Time: 11:29
*/
$ar = [5, 8, 6, 4, 12, 5, 3, 1, 89, 54];
echo "input: <br/>";
print_r(json_encode($ar));
echo "<br/>";
selection($ar);
echo "result: <br/>";
print_r(json_encode($ar));
echo "<br/>";
/** 最佳化的選擇排序
* @param array $ar
* @param null $len
*/
function selection(array & $ar, $len = null)
{
if ($len === null) {
$len = sizeof($ar);
}
for ($left = 0, $right = $len - 1; $left < $right; $left++, $right--) {
$min = $left; //consider left as min_index and max_index
$max = $right;
for ($j = $left + 1; $j <= $right; $j++) {//find min_index max_index
if ($ar[$j] <= $ar[$min]) {
$min = $j;
}
if ($ar[$j] >= $ar[$max]) {
$max = $j;
}
}
//check min_index and swap
if ($min != $left) {
$t = $ar[$left];
$ar[$left] = $ar[$min];
$ar[$min] = $t;
}
if ($max != $right) {
$t = $ar[$right];
$ar[$right] = $ar[$max];
$ar[$max] = $t;
}
echo "after 1 times: <br/>";
print_r(json_encode($ar));
echo "<br/>";
}
}
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/132/viewspace-2818162/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- php實現 氣泡排序,插入排序,選擇排序PHP排序
- PHP 排序演算法之選擇排序PHP排序演算法
- 常用演算法-選擇排序演算法排序
- 排序演算法:選擇排序排序演算法
- 排序演算法__選擇排序排序演算法
- python實現常用五種排序演算法Python排序演算法
- 選擇排序(python)實現排序Python
- 排序演算法 - 氣泡排序和選擇排序排序演算法
- Python排序演算法之 選擇排序Python排序演算法
- 排序演算法入門:選擇排序排序演算法
- 排序演算法之「選擇排序(SelectionSort) 」排序演算法
- C#實現——十大排序演算法之選擇排序C#排序演算法
- 深入淺出的排序演算法-選擇排序排序演算法
- 選擇排序和插入排序(C++實現)排序C++
- PHP基礎演算法之選擇排序法PHP演算法排序
- 排序演算法(氣泡排序,選擇排序,插入排序,希爾排序)排序演算法
- 排序演算法入門之「選擇排序」排序演算法
- PHP 常見4種排序 氣泡排序、選擇排序、插入排序、快速排序PHP排序
- 演算法基礎:排序演算法:選擇排序演算法排序
- python實現氣泡排序、插入排序以及快速排序演算法Python排序演算法
- Python八大演算法的實現,插入排序、希爾排序、氣泡排序、快速排序、直接選擇排序、堆排序、歸併排序、基數排序。Python演算法排序
- JavaScript實現常用排序演算法JavaScript排序演算法
- PHP 實現堆, 堆排序以及索引堆PHP排序索引
- java選擇排序演算法Java排序演算法
- 七、排序,選擇、冒泡、希爾、歸併、快速排序實現排序
- 畫江湖之演算法篇【排序演算法】選擇排序演算法排序
- 畫江湖之演算法篇 [排序演算法] 選擇排序演算法排序
- php實現4種排序演算法PHP排序演算法
- 經典排序演算法PHP實現排序演算法PHP
- Java實現二元選擇排序Java排序
- go slice/map型別 排序(選擇排序演算法)Go型別排序演算法
- 演算法學習之選擇排序和堆排序:演算法排序
- 選擇排序和快速排序排序
- 圖解選擇排序及演算法優化(Java實現)圖解排序演算法優化Java
- C#常用8種排序演算法實現以及原理簡介C#排序演算法
- php實現 歸併排序,快速排序PHP排序
- 選擇排序排序
- 資料結構與演算法——排序演算法-選擇排序資料結構演算法排序