數據結構之冒泡排序---PHP版

最近在複習數據結構,就寫一寫博客來記錄一下自己學習的路程。

一、冒泡排序很形象的就是最小的數字不斷往上冒泡,每冒泡一次最上面的數字就是最小的,這個過程很像在水裏冒泡一樣,所以就叫冒泡算法。

如上圖所示,這是經過了一次冒泡之後,2的位置從4變化到了1。所謂冒泡排序,最主要的思想就是兩兩比較,大的在下面小的在上面,這個過程也就是冒泡的過程。之後的冒泡過程也類似。經過6次冒泡,則成功將上面的集合變成有序集合。以下我用PHP代碼來實現一下(爲啥用PHP,因爲我堅信PHP是世界上最好的語言~~~有點沒底氣哈哈哈哈)

代碼1:

<?php

function maopao(&$list)
{

    $count = count($list);
    for ($i = 0; $i < $count; $i++) { //每循環一次就是一次冒泡的過程
        for ($j = $count – 1; $j > $i; $j–) {
            if ($list[$j – 1] > $list[$j]) {
                swap($list[$j – 1], $list[$j]);
            }
        }
    }
}
function swap(&$one, &$two)
{
    $tmp = $one;
    $one = $two;
    $two = $tmp;
}

?>

輸入:輸入一個數組集合 (不考慮非法輸入)  輸出:一個有序的數組

 

優化:我們仔細想一下,如果要排序的集合本身就比較有序,那冒泡排序算法是不是依然進行n次冒泡進行比較,只是不交換數據而已,這樣子的話就做了很多無用功,我們是不是可以考慮在數據不交換的時候就停止比較了呢?因此,我們可以考慮添加一個標誌位,在進行比較的時候如果不交換數據就置爲true,這樣就可以控制在數據不交換的時候就不進行比較了。以下是PHP實現

代碼2:

<?php

function maopao(&$list)
{

   $count = count($list);

    static $flag = true;
    for ($i = 0; $i < $count && $flag; $i++) { //每循環一次就是一次冒泡的過程

        $flag = false;
        for ($j = $count – 1; $j > $i; $j–) {
            if ($list[$j – 1] > $list[$j]) {
                swap($list[$j – 1], $list[$j]);

                $flag = true;
            }
        }
    }
    return $list;
}
function swap(&$one, &$two)
{
    $tmp = $one;
    $one = $two;
    $two = $tmp;
}

?>

只要添加一個標誌位來判斷它是否已經有序了,是否需要繼續冒泡,就可以減少不必要的比較,在性能方面還是提升了不少。這種性能在數據量比較大的時候還是能夠體現出來的。

時間複雜度:最好的情況下(在集合本身已經有序的情況下)冒泡排序只需要比較n-1次即可

最壞的情況下(在集合本身完全逆序的情況下)冒泡排序需要比較1+2+3+4+....n-1=n*(n-1)/2次

所以冒泡排序的時間複雜度爲O(n²),排序是穩定的

總結

冒泡排序很形象地就是小的數字不斷往上冒泡,最主要的思想就是兩兩交換,大的往下沉小的往上冒泡,每次冒泡最小的數字都冒泡到頂端。考慮到集合本身有序的情況,可以將有序之後做一些標識停止冒泡,這樣可以提升效率。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章