冒泡排序原理(升序):
原理
- 比较相邻元素:从数组第一个元素开始,比较相邻的两个元素。
- 交换位置:如果前一个元素比后一个元素大,就交换它们的位置。
- 重复遍历:对数组的每一对相邻元素重复这个过程,这样第一轮结束后,最大的元素会”沉”到数组末尾。
- 缩小范围:忽略已排序好的末尾元素,对剩余元素重复上述过程,直到整个数组有序。
冒泡排序就是不断地比较相邻两个数的大小并且判断是否交换位置。
可视化GIF动态图
下面是冒泡排序可视化的GIF动态图,便于理解。
静态过程图
为了方便理解和阅读的时候观看,这里也附上静态的过程图。

冒泡排序每一次都会将最大的那个数排到后面它该有的位置上, 所以每次比较次数都比上一次比较次数减少了一次
可以看到,5个数进行了4趟比较就会得出最终排序结果。这里的几趟就是下面代码中的外层循环。
每趟里面比较几次就是内层循环。
// 冒泡排序函数
void bubbleSort(int arr[], int n) // n是数组长度
{
for (int i = 0; i n - 1; i++) // 外层循环:控制排序趟数(n-1趟)
{
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;
}
}
}
}
代码解释
老规矩我们来逐行解释代码。以上面的数组{12,5,23,6,2}为案例。
for(int i=0;i
这行是外层循环,写的就是上面静态过程图中比较的趟数。案例中n是数组长度,也就是5。n-1就是4,也就是一共比较4趟
for (int j = 0; j
这是内层循环,写的就是静态过程图中每趟里面要比较的次数。比如第一趟里面比较4次。
刚刚说了冒泡排序每一次都会将最大的那个数排到后面它该有的位置上
也就是每趟排序会将未排序部分的最大的数变成已排序部分。
n-1-i 这里的减i实际上就是减的每趟比完变成了已排序部分的那个“未排序部分里的最大的数”
这里i=0,所以n-1-i=4,也就是j。那么j从0到4 (不包括4),就是4个数。刚好就是第一趟里面比较的次数。
if (arr[j] > arr[j + 1])
这行用来判断相邻元素的大小。我们将索引为j的看成当前元素,那么当前元素的下一个元素就是j+1。
int temp = arr[j];
接下来就是开始交换数据了。
这里定义一个temp中间变量用来存放要被交换的当前元素。
也就是当前元素arr[j]里面的数据赋值给了temp。
此时arr[j]就是一个空壳。
根据上面的内存循环语句for (int j = 0; j 我们知道j=0,也就是arr[0]的值赋值给temp。
| 原来的数组 | 12 | 5 | 23 | 6 | 2 |
|---|---|---|---|---|---|
| 下标/索引(j) | 0 | 1 | 2 | 3 | 4 |
temp 没有数据
改了之后:
| 现在的数组 | 空格 | 5 | 23 | 6 | 2 |
|---|---|---|---|---|---|
| 下标/索引(j) | 0 | 1 | 2 | 3 | 4 |
temp = 12
arr[j] = arr[j + 1];
这行就是将当前元素的下一个元素的数值赋值给当前元素。
也就是arr[0] = arr[1]
将arr[1]的值5赋值给变为空壳子的arr[0]
然后arr[1]变成空壳子
| 现在的数组 | 5 | 空格 | 23 | 6 | 2 |
|---|---|---|---|---|---|
| 下标/索引(j) | 0 | 1 | 2 | 3 | 4 |
temp = 12
arr[j + 1] = temp;
这行继续交换,将temp中的值12放到arr[j+1]也就是arr[1]中。
| 现在的数组 | 5 | 12 | 23 | 6 | 2 |
|---|---|---|---|---|---|
| 下标/索引(j) | 0 | 1 | 2 | 3 | 4 |
temp = 12
这样就完成了“第一趟”里的“第一次”比较。(arr[0]和arr[1]俩相比较)
接下来是第一趟里的第二次比较,就是让索引j=1作为当前元素,它的下一个元素j=2
也就是 arr[1]和arr[2]。重复上面的过程循环。
这就是整个冒泡排序的过程。
完整代码
#include
// 冒泡排序函数
void bubbleSort(int arr[], int n)
{
for (int i = 0; i n - 1; i++) // 外层循环:控制排序轮数(n-1轮)
{
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;
}
}
}
}
int main()
{
int arr[] = {5, 2, 9, 1, 5, 6}; // 待排序数组
int n = sizeof(arr) / sizeof(arr[0]); // 计算数组长度
// 打印原始数组
printf("原始数组: ");
for (int i = 0; i n; i++)
{
printf("%d ", arr[i]);
}
printf("n");
bubbleSort(arr, n); // 调用冒泡排序
// 打印排序后数组
printf("排序后数组: ");
for (int i = 0; i n; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
文章来源于互联网:排序算法(2)-冒泡排序
相关推荐: 防蚊防疫、防洪防汛…… 暑假安全承诺书怎么收?老师用这招超省力
暑假到了,孩子玩得开心,安全防护可不能松。 防溺水、防洪防汛、交通安全、食品安全,最近还要重点盯着防蚊防疫和基孔肯雅热预防…… 这些都得老师和家长一起使劲:发安全通知、收责任书签字、做每日安全打卡…… 事儿多又杂,老师怎么快速搞定?推荐用接龙管家,…
5bei.cn大模型教程网










