冒泡排序(Bubble Sort)見名知意,就是從前至後依次比較相鄰的兩個數據的大小,將大的往後移動,這樣經過一次完整的比較和移動,就可以將序列中最大的一個數放置到序列的最後,這也就是它名字的由來,就像水裏的水泡一樣, 越往上浮越大。
算法過程:
- 比較相鄰的元素,如果第一個比第二個大,就交換兩個的位置。
- 從序列的開頭一直到結尾一直重複這樣的工作,這樣一趟結束夠就可以將最大的數放置到最後。
- 進行第二趟排序,但最後一個數不需要參與計較,因爲它已經是最大的。
- 針對每次越來越少的數據進行N趟這樣的重複操作,整個序列有序。
如下圖所示,藍色框表示沒有發生交換,紅色框表示發生交換。
基於這樣的思想,可以寫出如下代碼:
void BubbleSort(int* array,int size)
{
for(int i = 0;i < size;++i)
{
for(int j = 0;j < size - i;++j)//每經過一次排序,最後一位已經最大,不需要再排
{
if(array[j] > array[j+1])
swap(array[j],array[j+1]);
}
}
}
優化:
如果一個待排序列經過較少次的比較和移動已經有序呢?
0 1 2 3 4 5 6 7 9 8 //一次排序交換9和8就已經有序,但還是要進行n(n -1)/2次比較,就顯得做無用功了。
冒泡排序中,如果一趟完整的比較中沒有數據之間的交換,那麼序列一定是已經有序了,不需要再進行之後的比較了。可以定義一個變量flag,來標記是否發生交換,如果沒有交換,就直接退出程序了。
如下:
void BubbleSort1(int* array, int size)
{
assert(array);
bool Flag = false;
for (int i = 0; i < size; ++i)
{
for (int j = 0; j < size - i; ++j)
{
if (array[j] > array[j + 1])
swap(array[j], array[j + 1]);
Flag = true;
}
if (!Flag)
break;
}
}
時間複雜度:
冒泡排序一共要進行n趟排序過程,然後第一趟比較n個數據,第二趟n-1,以此類推。
所以一共進行了n(n-1)/2,即n²+n/2次,故時間複雜度爲O(n²)。