#include <stdio.h>
#include <stdbool.h> // 用于bool类型
// 1. 基础版冒泡排序
void bubble_sort_basic(int arr[], int n) {
// 外层循环控制排序轮次(n-1轮)
for (int i = 0; i < n - 1; i++) {
// 内层循环执行相邻元素比较和交换
for (int j = 0; j < n - 1 - i; j++) {
// 前>后则交换(升序排列)
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
// 2. 检测交换点提前终止
void bubble_sort_optimized(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
bool swapped = false; // 交换标志位
for (int j = 0; j < n - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
// 执行交换
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
swapped = true; // 标记发生交换
}
}
// 本轮无交换说明已有序,提前结束
if (!swapped) break;
}
}
// 3. 边界版(动态收缩)
void bubble_sort_boundary(int arr[], int n) {
int last_swap_index = 0; // 记录最后交换位置
int sort_boundary = n - 1; // 无序区边界
for (int i = 0; i < n - 1; i++) {
bool swapped = false;
for (int j = 0; j < sort_boundary; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
swapped = true;
last_swap_index = j; // 更新最后交换位置
}
}
// 更新边界为最后一次交换的位置
sort_boundary = last_swap_index;
// 无交换则提前终止
if (!swapped) break;
}
}
// 4. 双向冒泡排序
void bubble_sort_bidirectional(int arr[], int n) {
int left = 0; // 左边界
int right = n - 1; // 右边界
bool swapped = true; // 交换标志
while (left < right && swapped) {
swapped = false;
// 正向遍历(左→右):移动最大值到右侧
for (int i = left; i < right; i++) {
if (arr[i] > arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
swapped = true;
}
}
right--; // 右边界收缩
// 反向遍历(右→左):移动最小值到左侧
for (int i = right; i > left; i--) {
if (arr[i] < arr[i - 1]) {
int temp = arr[i];
arr[i] = arr[i - 1];
arr[i - 1] = temp;
swapped = true;
}
}
left++; // 左边界收缩
}
}
// 打印数组
void print_array(int arr[], int n) {
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
int main() {
int original[] = {79,45,12,3,23,64, 34, 25, 12, 22, 11, 90};
int n = sizeof(original) / sizeof(original[0]);
// 复制数组用于不同排序方法
int arr1[n], arr2[n], arr3[n], arr4[n];
for(int i = 0; i < n; i++) {
arr1[i] = original[i];
arr2[i] = original[i];
arr3[i] = original[i];
arr4[i] = original[i];
}
printf("原始数组: ");
print_array(original, n);
// 测试不同排序算法
bubble_sort_basic(arr1, n);
printf("基础版: ");
print_array(arr1, n);
bubble_sort_optimized(arr2, n);
printf("优化版: ");
print_array(arr2, n);
bubble_sort_boundary(arr3, n);
printf("边界优化: ");
print_array(arr3, n);
bubble_sort_bidirectional(arr4, n);
printf("双向冒泡: ");
print_array(arr4, n);
return 0;
}
算法特点对比表:
算法类型 |
时间复杂度 |
空间复杂度 |
优化点 |
适用场景 |
基础版 |
O(n²) 始终 |
O(1) |
无 |
教学演示/小数据集 |
优化版(提前终止) |
O(n²)~O(n) |
O(1) |
检测到有序时提前终止 |
部分有序数据 |
边界优化版 |
O(n²)~O(n) |
O(1) |
动态缩小无序区边界 |
尾部有序的大数据集 |
双向冒泡(鸡尾酒) |
O(n²)~O(n) |
O(1) |
双向交替扫描 |
元素分布不均匀的数据集 |
执行结果示例:
原始数组: 79 45 12 3 23 64 34 25 12 22 11 90
基础版: 3 11 12 12 22 23 25 34 45 64 79 90
优化版: 3 11 12 12 22 23 25 34 45 64 79 90
边界优化: 3 11 12 12 22 23 25 34 45 64 79 90
双向冒泡: 3 11 12 12 22 23 25 34 45 64 79 90