冒泡排序 (bubble sort):如将一组数据排列为升序
步骤:
1.比较相邻元素,如果第一个元素比第二个元素大,就交换它们两个
2.对此时第二个元素和第三个元素进行同样的操作,依次对接下来每对元素进行相同操作,第一轮排序结束时,尾元素值应为最大值
3.重复以上步骤,但每轮结束时,下一轮参加比较的元素应减少1个(尾元素)
4.当剩余元素个数不足两个时,无法比较,排序结束
图示:
1.若当前数组中元素为如下降序存储
10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
进行上述步骤1的操作后,数组排序如下
9 | 10 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
2.依据步骤2,当一轮排序结束后,数组排序如下
9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 10 |
此时尾元素值为最大值10,在接下来的排序中,此元素不参加
3.依次按步骤进行排序
第二轮排序后,结果如下
8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 9 | 10 |
第三轮排序后,结果如下
7 | 6 | 5 | 4 | 3 | 2 | 1 | 8 | 9 | 10 |
......
第九轮排序后,结果如下
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
此时,只有1个元素,无法进行比较,而如图所示排序此时已经结束。因此,排序10个元素共需要进行9轮冒泡排序,以此类推,排序 sz 个元素需要 sz-1次冒泡排序,而每轮排序后下一轮参加排序的元素减少1个,若将10个元素排序,第一轮排序需要进行9次比较,第二轮排序需要进行8次比较,以此类推,排序 sz 个元素时,第 n 轮需要进行比较的次数为 sz-n 次
优化:
以上排序需要一轮一轮依次进行,直到只剩一个元素,但若是其中有一轮排序后已经达到了我们想要的顺序,那么接下来的排序就只是比较了但不会交换位置,这样会造成一定浪费。
因此,可以设置一个标志,将它的初始值置为1,若是还需要进行交换操作,就把它置为0。对此标志进行检查,若为0,说明还未达到需要的顺序,若为1,说明已经达到,排序结束。
代码实现如下:
#include<stdio.h>
void bubble_sort(int arr[], int sz)
{
int i = 0;
//sz个元素要进行sz-1趟冒泡排序
for (i = 0; i < sz-1 ; i++)
{
int j = 0;
//标志,当达到了想要的顺序,无需排序了,就为1,否则为0
int flag = 1;
//第n趟排序要进行sz-n次比较,由于i初始为0,这里n=i+1
//因此要进行sz-i-1次比较
for (j = 0; j < sz - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
//元素交换
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
//需要交换说明数组内元素还不是想要的顺序,把flag置0
flag = 0;
}
}
//flag为1时一定是没有进入上面的交换,说明已经是想要的顺序,跳出循环
if (flag == 1)
{
break;
}
}
}
int main()
{
int i = 0;
//定义一个数组
int arr[] = { 10,9,8,7,8,6,5,4,3,2,1 };
//数组元素个数
int sz = sizeof(arr) / sizeof(arr[0]);
printf("排序前:");
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
//冒泡排序
bubble_sort(arr, sz);
printf("排序后:");
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
运行结果如下: