冒泡排序法

来源:互联网 发布:淘宝最帅男模特顾义伟 编辑:程序博客网 时间:2024/06/10 12:57

冒泡排序(Bubble Sort)是一种简单直观的排序算法。

基本想:

在要排序的一组数中,对当前还未排好序的范围内的全部数,对相邻的两个数依次进行比较和调整,

让较大的数往冒(向后移),较小的往下沉(向前移)。(跟水底的泡泡一样,越往上泡泡越大)。

算法步骤:

1)比较相邻的元素。如果第一个比第二个大,就交换他们两个。

2)对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。

3)针对所有的元素重复以上的步骤,除了最后一个。

4)持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

冒泡排序的图示:


算法实现:

  function bubble(array){        var temp;        for(var i=0;i<array.length-1;i++){//长度-1是防止数组越界,虽然JavaScript不存在数组越界            for(var j=0;j<array.length-1-i;j++){//长度-1-i是因为每次比较之后,最后i个数都不需要再比较*                    if (array[j]>array[j+1]) {//如果前一个数比后一个数大,则交换这两数的位置                        temp=array[j];                        array[j]=array[j+1];                         array[j+1]=temp;                    }            }        }        return array;    }

注释*:举个例子,数组[5,4,3,2,1]

第一次排序是4,3,2,1,5  共比较4次,由于5已经是最大的那个数,所以下一次比较不需要再比较最后一个数;

第二次排序是3,2,1,4,5  共比较3次,由于4,5已经排好,所以下次比较不需要再比较后两位;

第三层排序是2,1,3,4,5  共比较2次,由于3,4,5已经排好,所以下次比较不需要再比较后三位;

第四层排序是1,2,3,4,5  共比较1次,排序完成。


算法分析:

在注释*的数组中,一共有5个数字,第一轮排序进行了4次,第二轮排序进行了3次,第三轮排序进行了2次,第四轮排序进行了1次。如果元素总数为N,则一共需要比较的次数为:

(N-1)+ (N-2)+ (N-3)+ ...1=N*(N-1)/2

根据大O表示法,常数可以忽略不计,那么冒泡排序法的时间复杂度为O(N2)。

冒泡排序的改进:

①加入标志性变量。

原理:如果上一轮的排序中,没有发生数据改变,那么说明排序已经完成。

代码实现:

 function bubble(array){        var temp;                  for(var i=0;i<array.length-1;i++){//长度-1是防止数组越界            var flag=false;//设置是否交换了变量            for(var j=0;j<array.length-1-i;j++){                    if (array[j]>array[j+1]) {                        temp=array[j];                        array[j]=array[j+1];                         array[j+1]=temp;                        flag=true;//本次排序发生了交换                    }            }            if(!flag) break; //如果本次排序之后没有进行交换,说明排序已经完成        }               return array;    }
②双向冒泡排序法

原理:将传统的冒泡排序法双向进行,先让气泡从左往右进行,再让气泡从右往左进行,一次循环确定最大right、最小值left。然后循环进行,确定次大次小值。多次循环之后,left>right,排序完成。

代码实现:

function bubble(array) {        var left = 0,            right = array.length - 1,            temp;        while (left <= right) {            for (var i = left; i < right; i++) { //从左往右进行,确定最大值                if (array[i] > array[i + 1]) { //如果左边的大于右边,则交换位置                    temp = array[i];                    array[i] = array[i + 1];                    array[i + 1] = temp;                }            }            --right; //下次开始,最右left个数不用判断            for (var j = right; j > left; j--) { //从右往左进行,确定最小值                if (array[j - 1] > array[j]) { //如果左边的大于右边,则交换位置                    temp = array[j - 1];                    array[j - 1] = array[j];                    array[j] = temp;                }            }            ++left; //下次开始,最左right个数不用判断        }        return array;    }

由于冒泡算法时间复杂度较高,即便是改进之后,在实际应用中仍然较少。有兴趣的同学可以去参考资料里面学习相关内容。

参考资料:

http://blog.csdn.net/u012152619/article/details/47305859

http://blog.csdn.net/fulei1107655988/article/details/38369833

http://blog.jobbole.com/11745/



原创粉丝点击