引言
冒泡排序是我在上大一学习C语言过程中授课老师给我们讲的第一个算法,也是我在编程道路上学会的第一个算法。
原理解释
冒泡排序就和它的名字一样,像水中的气泡一样从最底下往上升。较小的元素会逐渐向序列的一端“漂浮”或“冒泡”起来,而较大的元素则沉到另一端。每一轮遍历都会确保至少有一个元素(通常是最后一个未排序的元素)到达其最终的正确位置。
其基本思想是重复地遍历需要排序的数列,每次遍历时通过两两比较相邻元素,如果他们的顺序错误(即前一个比后一个大或相反),就交换这两个元素的位置。这个过程会一直持续到没有更多的元素需要交换为止,也就是数列已经排序完成。
附一张原理图
基本步骤
- 初始化:选择一个方向(升序或降序),并从序列的第一个元素开始。
- 比较与交换:比较相邻的元素。如果第一个比第二个大(对于升序排序),则交换它们;反之亦然。
- 继续遍历:继续对每一对相邻元素执行步骤2,直到列表的末尾。
- 重复:重复步骤2和3,但是每次遍历都忽略已正确排序的部分(通常是序列的尾部)。
- 终止条件:当没有更多的交换发生时,排序完成
代码实现
#include <stdio.h>
int main() {
int arr[10];
int temp;
for (int i = 0; i < 10; i++) {
scanf("%d", &arr[i]);
}
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 9 - i; j++) {
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
for (int i = 0; i < 10; i++) {
printf("%d", arr[i]);
}
return 0;
}
效果
Tips
在代码中第二层for循环中”j<9-i"的原因是在每轮遍历中,最后一个元素(或称当前轮次的最后一个未排序元素)会被放置到它应该处于的正确位置。随着遍历的进行,每一轮都会将一个元素放到它的最终位置上,因此下一轮就不需要再考虑这个元素了。
以升序排序为例:
- 第一轮:需要进行
n-1
次比较,将最大的元素移到数组的最后。 - 第二轮:需要进行
n-2
次比较,将次大的元素移到倒数第二个位置。 - 第三轮:需要进行
n-3
次比较,将第三大的元素移到倒数第三个位置。 - ...
- 最后一轮:需要进行
1
次比较,将仅剩的两个元素进行比较并排序。
总结来说,每轮遍历的比较次数如下表所示:
轮次 | 比较次数 |
---|---|
1 | n - 1 |
2 | n - 2 |
... | ... |
n-1 | 1 |
总结
冒泡排序虽然简单易懂,但由于其较高的时间复杂度,在实际应用中通常只适用于小型数据集或教学演示。对于大规模数据的排序,更高效的算法如快速排序、归并排序等通常更加合适。
Comments 1 条评论
博主 Soft and Wet
牛逼啊