標準冒泡排序每輪只將最大元素「冒泡」到右端,小元素像「烏龜」一樣慢速向左移動。雙向氣泡排序(Cocktail Sort / Shaker Sort)每輪雙向掃描:先右向左將最小元素移至左端,再左向右將最大元素移至右端,雙向縮小無序區,顯著減少「烏龜」元素的移動次數。
#include <stdio.h>
typedef int Elem;
typedef struct { Elem key; int data; } Sqlist;
// 雙向氣泡排序
void cocktailsort(Sqlist R[], int n) {
int left = 0, right = n - 1;
int swapped = 1;
while (swapped && left < right) {
swapped = 0;
// 右向左:將最小元素移到 left
for (int j = right; j > left; --j) {
if (R[j].key < R[j-1].key) {
Sqlist tmp = R[j];
R[j] = R[j-1];
R[j-1] = tmp;
swapped = 1;
}
}
++left; // 左邊界收縮
// 左向右:將最大元素移到 right
for (int j = left; j < right; ++j) {
if (R[j].key > R[j+1].key) {
Sqlist tmp = R[j];
R[j] = R[j+1];
R[j+1] = tmp;
swapped = 1;
}
}
--right; // 右邊界收縮
}
}
int main() {
Sqlist arr[10];
for (int i = 0; i < 10; ++i) {
arr[i].key = 10 - i;
arr[i].data = i;
}
cocktailsort(arr, 10);
for (int i = 0; i < 10; ++i)
printf("key:%d data:%d\n", arr[i].key, arr[i].data);
return 0;
}
left++/right-- 減少比較次數。swapped==0),說明已有序,立即結束。| 指標 | 標準冒泡 | 雙向氣泡 |
|---|---|---|
| 最好情況 | O(N) | O(N) |
| 平均/最壞 | O(N²) | O(N²) |
| 空間複雜度 | O(1) | O(1) |
| 穩定性 | 穩定 | 穩定 |
雙向氣泡在隨機資料下比標準冒泡快約 20%-30%,但在大規模資料下仍不如快排、堆排、歸併排。適合小規模、近乎有序、教學演示場景。
key:1 data:9 key:2 data:8 key:3 data:7 key:4 data:6 key:5 data:5 key:6 data:4 key:7 data:3 key:8 data:2 key:9 data:1 key:10 data:0
雙向氣泡排序是冒泡排序的經典優化變體,通過雙向掃描與邊界收縮顯著改善「烏龜」元素移動效率。代碼簡潔、原地排序、穩定,是理解排序演算法優化思想的優秀教學案例,但工程上大數據量請使用 O(N log N) 演算法。