冒泡排序(Bubble Sort)是一種簡單的排序方法,本文從排序思想、算法實現和算法分析等個方面介紹如下:
一、排序思想
一次比較相鄰兩個元素,如果他們的順序錯誤就把他們交換過來,重複地進行直到沒有再需要交換。
具體步驟如下:
- 依次比較相鄰兩個元素,首先比較第1個位置和第2個位置的數,大的放後面,小的放前面,然後比較第2個位置第3個位置的數,重複進行到第n個位置,經過這一輪,數組中最大元素交換到第n個位置;
- 重複上一步驟,直到第n-1個位置;依次重複執行,直到第1個位置
二、算法實現
// 冒泡排序算法
// arr : 堆數組指針
// len : 數組長度
void bubbleSort(int arr[], int len) {
int temp;
for (int i = len - 1; i > 0; i--) {
for (int j = 0; j < i; j++) {
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
三、算法分析
冒泡排序算法比較簡單容易理解,其算法時間複雜度爲O(n^2),空間複雜度爲O(1).冒泡排序過程中涉及到大量的元素交換,不適合於規模較大且亂序的場景,若初始狀態基本有序(指正序),可以採用冒泡排序。
四、算法改進
冒泡排序每次都需要從頭開始相鄰元素逐一比較,忽略了前輪比較結果而造成效率浪費。
一種改進的方案是交替方向掃描,即雙向冒泡排序,又稱爲雞尾酒排序。具體實現如下:
// 雞尾酒排序: 冒泡排序改進算法
// arr : 待排序數組
// len : 數組長度
void cocktailSort(int arr[], int len) {
int head = 0, tail = len - 1;
int temp, k;
while (head < tail) {
for (k = head; k < tail; k++) {
if (arr[k] > arr[k + 1]) {
temp = arr[k], arr[k] = arr[k + 1], arr[k + 1] = temp;
}
}
tail--;
for (k = tail; k > head; k--) {
if (arr[k - 1] > arr[k]) {
temp = arr[k], arr[k] = arr[k - 1], arr[k - 1] = temp;
}
}
head++;
}
}
另一種改進做法是設置一個標誌,若在一輪掃描過程中沒有交換元素,則表示已經排序完成,沒必要繼續執行。
// 改進冒泡排序算法,設置標誌
// arr : 堆數組指針
// len : 數組長度
void bubbleFlagSort(int arr[], int len) {
int temp, flag = 1;
for (int i = len - 1; i > 0 && flag; i--) {
flag = 0;
for (int j = 0; j < i; j++) {
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
flag = 1;
}
}
}
}