冒泡排序的基本思想是:每次比较两个相邻的元素,如果他们的顺序错误就把他们交换过来。
举个简单的例子,现在有一个数组【45,26,59,28,84,79】,我们需要将它变成从大到小排序。那么跟着冒泡排序的思想,首先将第一个位置上值与第二个位置的值进行比较,小的在前面大的在后面,45比26大,所以交换位置。接着将第二个位置的4值与第三个位置的值进行比较,45比59要小,就不需要交换位置。以此类推,我们发现数组变成了【26,45,29,59,79,84】,再次使用冒泡排序直到数组顺序正常。
第一次比较完成以后i和j的位置往后移,再次比较下一组数
直到第一轮比较全部完成,数组变成【26,45,28,59,79,84】,排序还是没有完成,但是可以发现最后一个数的位置是正确,它比前面的数都要的大。所以在进行第二轮比较的时候,我们就可以不对最后一位进行操作。
接下来我们用代码来表示冒泡排序,这里我以java为例
public void bubble(){
int a[]={10,23,11,56,45,26,59,28,84,79};//声明要进行排序的数组
int i,temp,flag=1;//声明i,temp用来存储索引对应的值,flag声明一个标识,对冒泡排序的一种优化
在这里声明了需要进行排序操作的数组a,索引i和存储索引值的temp,还有一个标识flag,用来对冒泡排序的优化。
for(i=0;i<a.length&&flag==1;i++){
//开始循环i
flag=0;//改变标识状态
for(int j=0;j<a.length-1;j++){
//循环j,比较a[j]和a[j+1]的值
if(a[j]>a[j+1]){
//如果符合条件的,就交换位置,重新设置标识
flag=1;
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
标识在符合条件的时候就改变状态为1,说明排序还未完成,标识为1就再次进行循环,当标识不为1时排序完成,停止循环,就减少了循环次数提高效率
System.out.println("\n 排序后的数组:");
for(i=0;i<a.length;i++){
System.out.print(a[i]+" ");
}
输出看看结果
最后我们总结一下:如果有n个数进行排序,只需将n-1个数归位,也就是说要进行n-1趟操作。而“每一趟”都需要从第1位开始进行相邻两个数的比较,将较小的一个数放在后面,比较完毕后向后挪一位继续比较下面两个相邻数的大小,重复此步骤,直到最后一个尚未归位的数,已经归位的数则无需再进行比较。
冒泡排序的核心部分是双重嵌套循环。不难看出冒泡排序的时间复杂度是O(N2)。这是一个非常高的时间复杂度。冒泡排序早在1956年就有人开始研究,之后有很多人都尝试过对冒泡排序进行改进,但结果却令人失望。如Knuth(Donald E. Knuth中文名为高德纳,1974年图灵奖获得者)所说:“冒泡排序除了它迷人的名字和导致了某些有趣的理论问题这一事实之外,似乎没有什么值得推荐的。