冒泡排序和选择排序

这周在逆战班学习了数组的排序算法,它的作用就是将数组中的数值,按照执行的顺序从小到大的排序,而排序算法的核心内容就是冒泡排序和选择排序。
1.冒泡排序
原理:数组中相邻的两个单位,比较存储数据的大小,如果第一个单元的数据大,就将两个相邻单元交换存储数据,从而实现从小到大的排序。
话不多说,先看下代码:

var arr = [5, 4, 3, 2, 1];

    //外层循环操作,控制排序的的次数是单元个数-1,因为前面的数排序完毕,最后一个不需要排序也会在最前面了
    for (var j = 0; j <= (arr.length - 1)-1; j++) {
        //内层循环控制每次循环比较一个最大值,每一个单元在倒数第二次就已经和最后一个单元比较完毕,因此优化代码-1,已经排序完毕的单元不需要再次参与循环-j
        for (var i = 0; i <= (arr.length - 1)-1-j; i++) {
            //通过if判断当前循环到的单元与下一单元之间的大小
            if (arr[i] > arr[i + 1]) {
                //只要结果为true,通过中间变量与下一位交换数据
                var m = 0;
                m = arr[i];
                arr[i] = arr[i + 1];
                arr[i + 1] = m;

            }
        }
    }
    // 排序完毕输出全新的数组
    console.log(arr);

这里就是一个简单的冒泡排序的实例,可以看到,我是通过两层for循环加上if判断和数据交换来实现的,那么这个过程究竟是怎么实现的呢?
过程:
首先当然是要有一个需要排序的数组,然后通过一个循环选出其中的最大值把它放到最后,最后在外层再套一层循环,控制排序的次数,这样外层每次循环,内层都会选出此次循环的最大数据放在后边,排序就实现了。
优化:最后是这个排序还有些优化
首先是内层的循环,通过循环比较方式选最大值的时候,事实上因为是当前单元与下一单元进行比较,那么当循环进行到倒数第二次的时候,最大值已经选出排好,那么循环长度就可以-1了,然后没选出一个数据,这个单元就不需要在参加了,因此这个数据也需要减掉,那么选出0个数据的时候是-0,一个数据的时候-1,以此类推就是选出多少个数据就减去几,也就是外层循环几次就减去几,所以最后还要-j,代码也就是:
i <= (arr.length - 1)-1-j
第二处需要优化的就是外层循环,最后一个单元不需要比较,因此是循环长度-1
j <= (arr.length - 1)-1
2.选择排序
原理:找到最小值的索引,与起始值交换数值
还是先上代码:
var arr = [3, 44, 38, 5, 47, 25, 36, 2, 79, 8, 1];

    // 外层循环,实现排序的循环次数,数组单元数-1
    for (var j = 0; j <= arr.length - 1 - 1; j++) {
        //定义变量min,作为内层循环初始值,这里赋值为j,因为每次循环都要从下一单元再次循环,所以这里每次循环正好随j进行变化
        var min = j;
        //内层循环,实现单元之间比较大小
        for (var i = j; i <= arr.length - 1; i++) {
            //通过if判断两个单元之间大小,这里是假设初始值是最小的,一旦出现数据比它小的,就对换两者索引值,由新的数据继续比较下去,一直到循环结束
            if (arr[min] > arr[i]) {
                min = i;
            }
        }
        //通过上边的循环已经对min重新赋值,这里在它不等于初始值的情况下,将当前索引下的数据与初始值对换实现排序
        if (min != j) {
            var m = 0;
            m = arr[j];
            arr[j] = arr[min];
            arr[min] = m;
        }
    }
    //输出全新数组
    console.log(arr);

过程:
同样是两层循环完成,这里还是从里往外写就好了,因为当里面操作完成之后,外面的循环也无非就是控制循环几次而已了。
1)定义一个变量,用它来作为我当前需要作比较的起始数值在数组中的索引下标
2)循环遍历数组
3)通过if判断进行比较,当前单元与后序所有单元进行比较,只要它比后面的单元存储的数据大,就把两者的索引下标交换。这个新的数据比之前的小,它会继续和后边的数据比较,最后得到最小的
4)通过第三步我已经获得了最小值,同时它的索引下标是min,那么我在进行一个判断,只要这个下标他和起始下标不一样,就把两者的数据交换,这样就把最小值换到了起始位置
5)最后就是外层循环,只要让min起始值等于外层循环当前的次数,那么每次都会是下一个数值向后比较,且不会和已经排好的冲突。
优化:同理,n个单元循环n-1次。
3.总结
选择排序:在发生大小顺序问题的时候,只做赋值索引的操作,等循环完成,执行判断,做一次数据交换。
冒泡排序:每次发生大小数据问题时,都要执行数据交换操作,执行数据交换的操作次数要比选择排序高,因此执行效率要低于选择排序。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值