问题描述:
输入一个原始数列,把它进行升序排序,从小到大输出。
例如:给定数列如下:
5 15 99 45 12 1 90 19 33 41
排序后的结果为:
1 5 12 15 19 33 41 45 90 99
冒泡排序顾名思义,就是让小的数一个一个的冒到上面来(最上面就是我们数组下标0),那么具体的做法是,从后往前两两进行比较,让两者中较小往上升,大家看一下下面这个过程:
下标值序号: 0 1 2 3 4 5 6 7 8 9
原始状态为: 5 15 99 45 12 1 90 19 33 41
第一趟排序: 1 5 15 99 45 12 19 90 33 41(遍历下标0-9,比较相邻的两个数,把小的交换到前面去)
第二趟排序: 1 5 12 15 99 45 19 33 90 41(遍历下标1-9,比较相邻的两个数,把小的交换到前面去)
第三趟排序: 1 5 12 15 19 99 45 33 41 90(遍历下标2-9,比较相邻的两个数,把小的交换到前面去)
第四趟排序: 1 5 12 15 19 33 99 45 41 90(遍历下标3-9,比较相邻的两个数,把小的交换到前面去)
第五趟排序: 1 5 12 15 19 33 41 99 45 90(遍历下标4-9,比较相邻的两个数,把小的交换到前面去)
第六趟排序: 1 5 12 15 19 33 41 45 99 90(遍历下标5-9,比较相邻的两个数,把小的交换到前面去)
第七趟排序: 1 5 12 15 19 33 41 45 90 99(遍历下标6-9,比较相邻的两个数,把小的交换到前面去)
大家可以看到,当我们完成第七趟排序之后,数列已经完全有序了,从这里我们可以发现:
1. 理论上来说,如果数列有N个数,最坏的情况下,需要N-1趟才能完全排好(因为每一趟一定能排好一个数)
2. 在大多数情况下,我们都可以小于N-1趟完成排序
3. 由上面的分析可以看出,本来以为需要9趟才能完成,现在7趟就已经完成了任务了,那么接下来我们就可以退出了,不必再做无用功了
4. 这个算法的时间复杂度是O(n^2)
参考代码:
#include<stdio.h>
int main()
{
int arr[] = { 5, 15, 99, 45, 12, 1, 90, 19, 33, 41 };
int i, j, nTemp, nIsAllSoft, nCount = sizeof(arr) / sizeof(arr[0]);
printf("排序前\n");
for (i = 0; i < nCount; i++)
printf("%d ", arr[i]);
printf("\n");
for (i = 0; i < nCount; i++)
{
nIsAllSoft = 1;//假定开始全部排好了,用C语言实现的,里面没有bool,也不想用char,就用int表示算了
for (j = nCount - 1; j > i; j--)//每次完成循环就至少排好了一个数,从下标为0开始
{
if (arr[j] < arr[j - 1])
{
nTemp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = nTemp;
nIsAllSoft = 0;//因为有交换所以没有排好
}
}
if (nIsAllSoft == 1)
break;
}
printf("\n排序后\n");
for (i = 0; i < nCount; i++)
printf("%d ", arr[i]);
printf("\n");
return 0;
}
运行结果: