先介绍一下冒泡排序 ,它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行,直到没有相邻元素需要交换,也就是说该元素列已经排序完成。
每次排序都会把最大或最小值排到顶部,像水中的泡泡一样,所以叫冒泡排序。
最普通的冒泡排序
#include <stdio.h>
#include <stdlib.h>
#define num 10
int main()
{
int a[num] = {4,6,1,2,9,8,10,3,5,7};
int i,j,temp;//i是数组位置,j是循环次数,temp是存放数组数据的临时变量
for(j = 0;j < num - 1;j++)
{
for(i = 0;i < num - 1;i++)
{
if(a[i] > a[i+1]){
temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
}
}
for(i = 0;i < 10;i++)
{
printf("%d,",a[i]);
}
printf("\n");
}
return 0;
}
我们可以看到结果j循环了9次,但是实际第5次循环的时候数组已经是有序序列了,所以可以改进,增加一个标识符,如果第j次循环,内部的数组第i个元素和第i+1个均未发生交换,则说明数组已有序。
改进版冒泡排序
#include <stdio.h>
#include <stdlib.h>
#define num 10
int main()
{
int a[num] = {4,6,1,2,9,8,10,3,5,7};
int i,j,temp,flag;//判断是否置换顺讯的标识符
for(j = 0;j < num - 1;j++)
{
flag = 1;
for(i = 0;i < num - 1;i++)
{
if(a[i] > a[i+1]){
flag = 0;
temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
}
}
if (flag)
break;//没有发生置换直接跳出循环
for(i = 0;i < 10;i++)
{
printf("%d,",a[i]);
}
printf("\n");
}
return 0;
}
我们可以看到,这次代码j只循环了6次,输出了5次。
在此之上,每一次最大的数字都会被放在第num-i的位置上,为了节省i循环次数,我们可以继续对代码进行改进
最优冒泡排序
#include <stdio.h>
#include <stdlib.h>
#define num 10
int main()
{
int a[num] = {4,6,1,2,9,8,10,3,5,7};
int i,j,temp,flag;
for(j = 0;j < num-1;j++)
{
flag = 1;
for(i = 0;i < num-1-j;i++)//每次最大的数,都不用再重新进入循环了
{
if(a[i] > a[i+1]){
flag = 0;
temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
}
}
if (flag)
break;
for(i = 0;i < 10;i++)
{
printf("%d,",a[i]);
}
printf("\n");
}
return 0;
}