算法思想
冒泡排序屬于一種典型的交換排序。就是通過元素的兩兩比較,判斷是否符合要求,如過不符合就交換位置來達到排序的目的。冒泡排序名字的由來就是因為在交換過程中,類似水冒泡,?。ù螅┑脑亟涍^不斷的交換由水底慢慢的浮到水的頂端。
冒泡排序原理
- 比較相鄰的元素。如果第一個比第二個大,就交換他們兩個
- 對每一對相鄰元素做同樣的工作,從開始第一對到結尾的最后一對。在這一點,最后的元素應該會是最大的數
- 針對所有的元素重復以上的步驟,除了最后一個
- 持續每次對越來越少的元素重復上面的步驟,直到沒有任何一對數字需要比較
冒泡排序流程圖.jpg
冒泡排序示例說明
將數組 10,1,35,61,89,36,55 進行排序
第一趟排序(找出最大值):
- 第一次排序:10和1比較,10大于1,交換位置 [1,10,35,61,89,36,55]
- 第二趟排序:10和35比較,10小于35,不交換位置 [1,10,35,61,89,36,55]
- 第三趟排序:35和61比較,35小于61,不交換位置 [1,10,35,61,89,36,55]
- 第四趟排序:61和89比較,61小于89,不交換位置 [1,10,35,61,89,36,55]
- 第五趟排序:89和36比較,89大于36,交換位置 [1,10,35,61,36,89,55]
- 第六趟排序:89和55比較,89大于55,交換位置 [1,10,35,61,36,55,89]
- 第一趟總共進行了六次比較,排序結果:[1,10,35,61,36,55,89]
第二趟排序(循環處理第一次處理的結果找出第二大的值):
- 第一次排序:1和10比較,1小于10,不交換位置 1,10,35,61,36,55,89
- 第二次排序:10和35比較,10小于35,不交換位置 1,10,35,61,36,55,89
- 第三次排序:35和61比較,35小于61,不交換位置 1,10,35,61,36,55,89
- 第四次排序:61和36比較,61大于36,交換位置 1,10,35,36,61,55,89
- 第五次排序:61和55比較,61大于55,交換位置 1,10,35,36,55,61,89
- 第二趟總共進行了5次比較,排序結果:1,10,35,36,55,61,89
第三趟排序:
- 第一次排序:1和10比較,1小于10,不交換位置 1,10,35,36,55,61,89
- 第二次排序:10和35比較,10小于35,不交換位置 1,10,35,36,55,61,89
- 第三次排序:35和36比較,35小于36,不交換位置 1,10,35,36,55,61,89
- 第四次排序:36和61比較,36小于61,不交換位置 1,10,35,36,55,61,89
- 第三趟總共進行了4次比較,排序結果:1,10,35,36,55,61,89
- 到目前位置已經為有序的情形了。
冒泡排序分析
N個數字要排序完成,總共進行N-1趟排序,每i趟的排序次數為(N-i)次,所以可以用雙重循環語句,外層控制循環多少趟,內層控制每一趟的循環次數
冒泡排序的優點:每進行一趟排序,就會少比較一次,因為每進行一趟排序都會找出一個較大值。如上例:第一趟比較之后,排在最后的一個數一定是最大的一個數,第二趟排序的時候,只需要比較除了最后一個數以外的其他的數,同樣也能找出一個最大的數排在參與第二趟比較的數后面,第三趟比較的時候,只需要比較除了最后兩個數以外的其他的數,以此類推……也就是說,沒進行一趟比較,每一趟少比較一次,一定程度上減少了算法的量。
php代碼實現
<?php
$arr = [10,1,35,61,89,36,55];
/**
* [bubbleSort 冒泡排序]
* @url示例:
* @DateTime:2020-03-29
* @邏輯:
* @param [type] $arr [排序的數組]
* @return [type] [排序完成的數組]
*/
function bubbleSort($arr)
{
$len=count($arr);
for ($i = 1; $i < $len; $i++) {
for ($k = 0; $k < $len - $i; $k++) {
if ($arr[$k] > $arr[$k + 1]) {
$tmp = $arr[$k+1];
$arr[$k+1] = $arr[$k];
$arr[$k] = $tmp;
}
}
}
return $arr;
}
echo '<pre>';
$result = bubbleSort($arr);
var_dump($result);
冒泡排序優化
針對問題
數據的順序排好之后,冒泡算法仍然會繼續進行下一輪的比較,直到arr.length-1次,后面的比較沒有意義的
方案
設置標志位flag,如果發生了交換flag設置為true;如果沒有交換就設置為false。這樣當一輪比較結束后如果flag仍為false,即:這一輪沒有發生交換,說明數據的順序已經排好,沒有必要繼續進行下去
php優化之后
<?php
$arr = [10,1,35,61,89,36,55];
/**
* [bubbleSort 冒泡排序]
* @url示例:
* @DateTime:2020-03-29
* @邏輯:
* @param [type] $arr [排序的數組]
* @return [type] [排序完成的數組]
*/
function bubbleSort($arr)
{
$len=count($arr);
$flag=null; //設置交換標識
for ($i = 1; $i < $len; $i++) {
$flag = false;
for ($k = 0; $k < $len - $i; $k++) {
if ($arr[$k] > $arr[$k + 1]) {
$tmp = $arr[$k+1];
$arr[$k+1] = $arr[$k];
$arr[$k] = $tmp;
$flag = true;
}
}
if(!$flag) break;
}
return $arr;
}
echo '<pre>';
$result = bubbleSort($arr);
var_dump($result);