今天跟同学探讨了排序算法中的冒泡排序,很早之前其实就写过这个代码,但是一直没有正式的写到博客中来,其实冒泡排序是九大排序中最简单的一个,也是最容易理解的一个排序,好了,废话不多说,我们先来谈一下冒泡排序的思想。
冒泡排序的思想:我们以从小到大排列为例,所谓冒泡排序就是在无序数组中每执行一趟选出这一趟中最大的数放在最后面,第二趟选出次大的数放在倒数第二位上,以此类推直到完成排序。下来贴代码:
第一种方式

var arr=[2,5,4,2,1];
var x;
for(var i=0;i<arr.length-1;i++){
    for(var j=0;j<arr.length-i-1;j++){
        if(arr[j]>arr[j+1]){
            x=arr[j+1];
            arr[j+1]=arr[j];
            arr[j]=x;
        }
    }
    console.log("第"+(i+1)+"趟排序后的数组是"+arr);
}
console.log(arr);

运行效果如下:

javascriptsort实现冒泡排序 js 冒泡排序法_冒泡排序

在这里我们用了两个循环来完成排序,第一个for循环是用来控制执行冒泡的趟数,这里为什么是arr.length-1,比如我们如果是两个数排序那么最多只需要比较一次就可以了,同样如果是n个数我们最多只需冒泡n-1次就可以了,第二个循环我们是用来控制每一趟冒泡所需比较的数的个数,这里为什么是arr.length-i-1,因为每冒泡一次就会选出一个最大值,然后下一次冒泡就不用再去比较前一趟所冒泡的最大值了所以长度就会减去i。
第二种方式
主要还是对第一种方式的优化,我们设置一个标志,如果这一趟发生了交换,则为true,否则为false。如果有一趟没有发生交换,则说明排序已经完成。代码如下:

var arr=[2,5,4,2,1];
var n=arr.length;  
var flag=true;  
while(flag)  
{  
      flag=false;  
      for(var j=1;j<n;j++){ 
            if (arr[j-1]>arr[j])  
            {  
                    x=arr[j-1];
                    arr[j-1]=arr[j];
                    arr[j]=x;
                    flag=true;  
            }
        }
        n--; 
}
console.log(arr);

第三种方式
是对前两种方式的进一步优化,假如数组长度是20,如果只有前十位是无序排列的,后十位是有序且都大于前十位,所以第一趟遍历排序的时候发生交换的位置必定小于10,且该位置之后的必定有序,我们只需要排序好该位置之前的就可以,因此我们要来标记这个位置就可以了,代码如下:

var arr=[2,5,4,2,1];
var n=arr.length;
var j,k;  
var flag=n;
while(flag>0)  
{  
    k=flag;  
    flag=0;  
    for(j=1;j<k;j++){ 
        if (arr[j - 1] > arr[j])  
        {  
            x=arr[j-1];
            arr[j-1]=arr[j];
            arr[j]=x;
            flag=j;  
        }  
    }  
} 
console.log(arr);

最后需要注意的是冒泡排序最好的时间复杂度为O(n),最坏是O(n^2),平均时间复杂度是O(n^2),且是稳定的排序算法,冒泡排序虽然说是一种简单且容易理解的排序,但是毕竟是一种效率低下的排序方法,在数据规模很小时,可以采用。