冒泡排序法

冒泡排序(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/



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值