php冒泡排序,兩種思路,時間復雜度都是O(n^2),當然最優的時間復雜度就是O(n),以下說的都是正序排列(倒序的話,把內層循環的大於號換成小於號就好了)
第一種冒泡排序
思路就是把第一個數跟所有的數比較,如果碰到比第一個數還小的數字,就把他倆位置交換下,然后把交換后的數字繼續往后比較...
這樣第一輪交換能得出什么呢,就是第一輪交換完,數組的第一個位置,一定是最小的數
循環體內,每次$j = $i + 1, 因為外層每循環一次已經把最小的數壓到數字頭部了, 沒必要從頭開始比較了
$numbers = array(-2, 5, 3, 1, -3, -4); for ($i=0;$i<count($numbers);$i++) { for ($j=$i+1;$j<count($numbers);$j++) { if ($numbers[$i] > $numbers[$j]) { $tmp = $numbers[$i]; $numbers[$i] = $numbers[$j]; $numbers[$j] = $tmp; } } // var_dump($numbers); } var_dump($numbers);exit;
第一輪交換的過程:拿數組的第一位-2跟5比,發現沒有我小,跳過,拿-2跟3比,發小沒有我小跳過...
拿-2跟-3比的時候,發小比我還小,兩個交換下位置,下次循環的時候數組第一位已經發生了變化,是-3。嗯,仔細想想
然后循環還沒完,繼續拿數組的第一位(-3),跟數組最后一位-4比較,又交換下位置...
結果:[-4, 5, 3, 1, -2, -3]
第二輪循環時候拿5跟數組后面的開始比較,沒必要跟前面的比了,因為經過上一輪的比較,第一位肯定是最小的...
第二種冒泡排序
思路就是一組一組數字(相鄰的兩個數)比較,如果大於后面的數字就發生交換,這樣比較完的結果就是會把最大的數移動到最后的位置
$numbers = array(-2, 5, 3, 1, -3, -4); for ($i = 0; $i < count($numbers); $i++) { for ($j = 0; $j < count($numbers) - $i - 1; $j++) { if ($numbers[$j] > $numbers[$j + 1]) { $temp = $numbers[$j]; $numbers[$j] = $numbers[$j + 1]; $numbers[$j + 1] = $temp; } } var_dump($numbers); }
第一輪交換完過程就是: -2不大於5不交換,5大於3交換,5大於1交換,5大於-3交換,5大約-4交換....
結果: [-2, 3, 1, -3, -4,5]
...
第二輪交換的時候,注意條件$j < count($numbers) - $i - 1; 已經不跟最后一個比較了,因為你懂的...
關於優化
如果數組是: [5,1,2,3,4] 套用我們第二種思路的話, 是不是我們第一輪循環完(結果是[1,2,3,4,5]), 就可以終止循環了.
加個變量,如果里面沒有發生交換,就意味着數組目前就是有序的,可以退出循環了
$numbers = [5,1,2,3,4]; for ($i = 0; $i < count($numbers); $i++) { $flag = 1; for ($j = 0; $j < count($numbers) - $i - 1; $j++) { if ($numbers[$j] > $numbers[$j + 1]) { $flag = 0; $temp = $numbers[$j]; $numbers[$j] = $numbers[$j + 1]; $numbers[$j + 1] = $temp; } } if($flag) break; } var_dump($numbers);exit;
