一提起冒泡排序,可能大家会很快写出这样的代码:
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
void BubbleSort(int *str,int len)
{
int i=0;
int j=0;
int tmp=0;
assert(str);
for(i=0;i<len-1;i++) //控制比较的趟数
{
for(j=0;j<len-i-1;j++)
{
if(str[j]>str[j+1])
{
tmp=str[j];
str[j]=str[j+1];
str[j+1]=tmp;
}
}
}
}
int main()
{
int arr[]={1,2,3,7,6,5,4,8,9,0};
int i=0;
BubbleSort(arr,10);
for(i=0;i<10;i++)
{
printf("%2d",arr[i]);
}
system("pause");
return 0;
}
但是这样的方法效率会很低哦,如果有n个元素会进行n-1趟比较,比如说:要升序排这样一个数组 1 2 3 4 7 9 8 观察一下,其实我们会发现对于这样一个例子来说完全没必要进行6趟比较,只需要1趟就可以解决问题的嘛。那么我们可不可以试着添加一个标记,用来判断是否进行了元素的交换,如果没有,那么就说明已经有序就直接可跳出循环了,下面我们通过代码来看看:
void BubbleSort(int *str,int len)
{
int i=0;
int j=0;
int tmp=0;
int flag=0; //代表有序
assert(str);
for(i=0;i<len-1;i++) //控制比较的趟数
{
flag=0; //每排序一趟必然有一个数字为有序的,可缩小范围
for(j=0;j<len-i-1;j++) //控制每趟比较的次数
{
if(str[j]>str[j+1]) //只要数组未完成所有排序,flag就会被修改
{
tmp=str[j];
str[j]=str[j+1];
str[j+1]=tmp;
flag=1;
}
}
if(flag==0)
{
break;
}
}
}
这样的话效率应该还行吧,但是还不是很理想,如果给出这样一组数:1 2 3 6 5 4 7 8 9 ,观察一下我们会发现前面3个和后面3个数都是有序的,我们可以在每次比较后记住最后一次交换的位置,这样可以减少比较的次数,下来我们通过图来分析一下:
通过以上的分析我们可以写出如下代码:
void BubbleSort(int *str,int len)
{
int i=0;
int j=0;
int tmp=0;
int m=0;
int k=len-1;
int flag=0; //代表有序
assert(str);
for(i=0;i<len-1;i++) //控制比较的趟数
{
m=0;
flag=0; //每排序一趟必然有一个数字为有序的,可缩小范围
for(j=0;j<k;j++) //控制每趟比较的次数
{
if(str[j]>str[j+1]) //只要数组未完成所有排序,flag就会被修改
{
tmp=str[j];
str[j]=str[j+1];
str[j+1]=tmp;
flag=1;
m=j; //记住一趟下来最后一次交换的位置
}
}
if(flag==0)
{
break;
}
k=m; //将k设置为最后一次交换的位置
}
}