1. 冒泡排序算法
基本概念与排序原理
冒泡排序作为最基础的排序算法,其核心思想是通过相邻元素的反复比较和交换,使得较大元素逐步"浮"到数组末端。下面我们以序列 [8, 7, 6, 3, 1] 的升序排列为例,详细解析其执行过程。
排序过程逐步分析
第一轮排序:
- 8与7比较:8>7,交换 →
[7, 8, 6, 3, 1] - 8与6比较:8>6,交换 →
[7, 6, 8, 3, 1] - 8与3比较:8>3,交换 →
[7, 6, 3, 8, 1] - 8与1比较:8>1,交换 →
[7, 6, 3, 1, 8]
第二轮排序:
- 7与6比较:7>6,交换 →
[6, 7, 3, 1, 8] - 7与3比较:7>3,交换 →
[6, 3, 7, 1, 8] - 7与1比较:7>1,交换 →
[6, 3, 1, 7, 8]
后续轮次依此类推,直到完全有序。
算法复杂度分析
- 时间复杂度:O(n²)
- 空间复杂度:O(1)
- 稳定性:稳定排序算法
代码实现
c
#include <stdio.h>
void bubbleSort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
// 交换相邻元素
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
int main() {
int n;
int arr[10];
printf("请输入元素个数(最多10个): ");
scanf("%d", &n);
printf("请输入%d个整数: ", n);
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
bubbleSort(arr, n);
printf("排序结果: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
2. 选择排序算法
基本概念与排序原理
选择排序的核心思想是:在未排序序列中反复寻找最小元素,将其存放到已排序序列的末尾。该算法将数组分为已排序和未排序两部分,每次从未排序部分选择最小元素进行交换。
排序过程逐步分析
以序列 [8, 7, 6, 3, 1] 为例:
第一轮:找到最小值1,与首位8交换 → [1, 7, 6, 3, 8]
第二轮:在剩余部分找到最小值3,与第二位7交换 → [1, 3, 6, 7, 8]
第三轮:找到最小值6,位置正确 → [1, 3, 6, 7, 8]
第四轮:找到最小值7,位置正确 → [1, 3, 6, 7, 8]
算法复杂度分析
- 时间复杂度:O(n²)
- 空间复杂度:O(1)
- 稳定性:不稳定排序算法
代码实现
c
#include <stdio.h>
void selectionSort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
int minIndex = i;
int minValue = arr[i];
// 在未排序部分寻找最小值
for (int j = i + 1; j < n; j++) {
if (arr[j] < minValue) {
minValue = arr[j];
minIndex = j;
}
}
// 将最小值交换到已排序序列末尾
if (minIndex != i) {
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
}
int main() {
int n;
int arr[10];
printf("请输入元素个数(最多10个): ");
scanf("%d", &n);
printf("请输入%d个整数: ", n);
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
selectionSort(arr, n);
printf("排序结果: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
3. 插入排序算法
基本概念与排序原理
插入排序采用类似整理扑克牌的思路:将每个新元素插入到已排序部分的适当位置。对于每个待排序元素,从后向前扫描已排序序列,找到相应位置并插入。
排序过程形象比喻
假设手中有 [1, 3, 4, 7, 8] 这些牌,新拿到数字6:
- 与8比较:6<8,继续向前
- 与7比较:6<7,继续向前
- 与4比较:6>4,找到插入位置
最终序列变为:[1, 3, 4, 6, 7, 8]
排序过程分析
以序列 [8, 7, 6, 3, 1] 为例:
- 第一轮:7插入到8之前 →
[7, 8, 6, 3, 1] - 第二轮:6插入到7之前 →
[6, 7, 8, 3, 1] - 第三轮:3插入到6之前 →
[3, 6, 7, 8, 1] - 第四轮:1插入到3之前 →
[1, 3, 6, 7, 8]
算法复杂度分析
- 时间复杂度:O(n²),最优情况下为O(n)
- 空间复杂度:O(1)
- 稳定性:稳定排序算法
代码实现
c
#include <stdio.h>
void insertionSort(int arr[], int n) {
for (int i = 1; i < n; i++) {
int current = arr[i]; // 当前待插入元素
int j = i - 1;
// 将比当前元素大的元素向后移动
while (j >= 0 && arr[j] > current) {
arr[j + 1] = arr[j];
j--;
}
// 插入当前元素到正确位置
arr[j + 1] = current;
}
}
int main() {
int n;
int arr[10];
printf("请输入元素个数(最多10个): ");
scanf("%d", &n);
printf("请输入%d个整数: ", n);
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
insertionSort(arr, n);
printf("排序结果: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
算法对比总结
| 排序算法 | 平均时间复杂度 | 最优情况 | 最差情况 | 空间复杂度 | 稳定性 | 适用场景 |
|---|---|---|---|---|---|---|
| 冒泡排序 | O(n²) | O(n) | O(n²) | O(1) | 稳定 | 小规模数据、教学用途 |
| 选择排序 | O(n²) | O(n²) | O(n²) | O(1) | 不稳定 | 小规模数据、交换次数少 |
| 插入排序 | O(n²) | O(n) | O(n²) | O(1) | 稳定 | 小规模或基本有序数据 |
这三种基础排序算法虽然时间复杂度较高,但作为算法学习的入门内容,它们能够帮助我们深入理解排序的基本原理和算法设计思想,为学习更高效的排序算法奠定坚实基础。