php算法之冒泡排序

算法思想

冒泡排序屬于一種典型的交換排序。就是通過元素的兩兩比較,判斷是否符合要求,如過不符合就交換位置來達到排序的目的。冒泡排序名字的由來就是因為在交換過程中,類似水冒泡,?。ù螅┑脑亟涍^不斷的交換由水底慢慢的浮到水的頂端。

冒泡排序原理

  1. 比較相鄰的元素。如果第一個比第二個大,就交換他們兩個
  2. 對每一對相鄰元素做同樣的工作,從開始第一對到結尾的最后一對。在這一點,最后的元素應該會是最大的數
  3. 針對所有的元素重復以上的步驟,除了最后一個
  4. 持續每次對越來越少的元素重復上面的步驟,直到沒有任何一對數字需要比較
冒泡排序流程圖.jpg

冒泡排序示例說明

將數組 10,1,35,61,89,36,55 進行排序

第一趟排序(找出最大值):

  1. 第一次排序:10和1比較,10大于1,交換位置      [1,10,35,61,89,36,55]
  2. 第二趟排序:10和35比較,10小于35,不交換位置  [1,10,35,61,89,36,55]
  3. 第三趟排序:35和61比較,35小于61,不交換位置  [1,10,35,61,89,36,55]
  4. 第四趟排序:61和89比較,61小于89,不交換位置  [1,10,35,61,89,36,55]
  5. 第五趟排序:89和36比較,89大于36,交換位置   [1,10,35,61,36,89,55]
  6. 第六趟排序:89和55比較,89大于55,交換位置   [1,10,35,61,36,55,89]
  7. 第一趟總共進行了六次比較,排序結果:[1,10,35,61,36,55,89]

第二趟排序(循環處理第一次處理的結果找出第二大的值):

  1. 第一次排序:1和10比較,1小于10,不交換位置  1,10,35,61,36,55,89
  2. 第二次排序:10和35比較,10小于35,不交換位置 1,10,35,61,36,55,89
  3. 第三次排序:35和61比較,35小于61,不交換位置 1,10,35,61,36,55,89
  4. 第四次排序:61和36比較,61大于36,交換位置   1,10,35,36,61,55,89
  5. 第五次排序:61和55比較,61大于55,交換位置   1,10,35,36,55,61,89
  6. 第二趟總共進行了5次比較,排序結果:1,10,35,36,55,61,89

第三趟排序:

  1. 第一次排序:1和10比較,1小于10,不交換位置  1,10,35,36,55,61,89
  2. 第二次排序:10和35比較,10小于35,不交換位置 1,10,35,36,55,61,89
  3. 第三次排序:35和36比較,35小于36,不交換位置 1,10,35,36,55,61,89
  4. 第四次排序:36和61比較,36小于61,不交換位置   1,10,35,36,55,61,89
  5. 第三趟總共進行了4次比較,排序結果:1,10,35,36,55,61,89
  6. 到目前位置已經為有序的情形了。

冒泡排序分析

  1. N個數字要排序完成,總共進行N-1趟排序,每i趟的排序次數為(N-i)次,所以可以用雙重循環語句,外層控制循環多少趟,內層控制每一趟的循環次數

  2. 冒泡排序的優點:每進行一趟排序,就會少比較一次,因為每進行一趟排序都會找出一個較大值。如上例:第一趟比較之后,排在最后的一個數一定是最大的一個數,第二趟排序的時候,只需要比較除了最后一個數以外的其他的數,同樣也能找出一個最大的數排在參與第二趟比較的數后面,第三趟比較的時候,只需要比較除了最后兩個數以外的其他的數,以此類推……也就是說,沒進行一趟比較,每一趟少比較一次,一定程度上減少了算法的量。

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);
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容