冒泡排序 (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,说明已经达到,排序结束。
代码实现如下:
#includevoid 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 temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; //需要交换说明数组内元素还不是想要的顺序,把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; }
运行结果如下:



