JS中的冒泡排序和选择排序方法最详细的解释

冒泡排序和选择排序对比详细讲解

文章流程:

算法思路 > 未优化代码 > 执行结果 > 执行流程分析 > 代码优化 > 优化思路

冒泡排序和选择排序是两个十分基础的算法,作为一个程序员,这些算法是必须要会的。

首先我们要说一下冒泡法和选择排序法的优缺点:
冒泡法相对于选择排序而言比较好理解,但是它却比选择排序执行时更繁琐、效率更低。

第一个我们来说一下比较好理解的:

冒泡排序法:

  1. 学习一个算法,首先要了解他的原理:
    所谓的冒泡法,就像水中的气泡一样,越往上气泡越大,同理,数组中的数值从左到右越往右越大。这就需要用到判断,如果左边的比紧挨着他的右边的数值大,则让他们两个交换,实现从小到大排列,思路合理开始执行!

基础代码(未优化):

<script>
        //冒泡法排序数组
        var arr1 = [23, 32, 123, 3, 4,];
        for (var j = 0; j <= arr1.length - 1 ; j++) {
            for (var i = 0; i <= arr1.length - 1 ; i++) {
                var middle = 0;
                if (arr1[i] > arr1[i + 1]) {
                    middle = arr1[i];
                    arr1[i] = arr1[i + 1];
                    arr1[i + 1] = middle;
                }
            }
        }
        console.log(arr1);
    </script>

执行结果:
在这里插入图片描述
执行流程:
我们要定义一个数组 arr1.
从内往外分析!!!!

  1. 先看内层循环:
    我们定义一个变量 i ,i也就是数组数据对应的索引,所以从0开始,到最后一个数据的索引下标:arr1.length-1。
    如同我们的思路一样,进行判断,如果前一个大于后一个则执行数据的交换,选出最大的一个放到最后。
    这里就需要设置一个中间变量,实现交换数据存储。这内层循环循环一次,选出了一个最大的数据,将他放在了数组最后。

  2. 再看外层循环:
    按照正常的简单思维呢,我们要将他们依次进行排序,那么有几个数据就要循环几次,所以外层循环定义一个变量 j 次,也是从0-arr1.length-1,这样也就实现了我们想要的效果。

代码优化:

<script>
        //冒泡法排序数组优化
        var arr1 = [23, 32, 123, 3, 4,];
        for (var j = 0; j <= arr1.length - 1 - 1; j++) {
            for (var i = 0; i <= arr1.length - 1 - 1 - j; i++) {
                var middle = 0;
                if (arr1[i] > arr1[i + 1]) {
                    middle = arr1[i];
                    arr1[i] = arr1[i + 1];
                    arr1[i + 1] = middle;
                }
            }
        }
        console.log(arr1);
    </script>

执行结果:
在这里插入图片描述
优化思路:
我们发现有三个地方发生了变化,依然从内往外看:

  1. 内层循环又减去了一个1.为什么要减去一个1呢?仔细想想,依次两两比较,当最后两个比较的时候是不是只需要比较一次就可以得出结果了呢?所以可以再减去一个1,减少程序计算量,提高效率。
  2. 内层循环又减去了一个j。为什么内层循环要再减去一个j次呢?很好理解,j=0时,我们进行了第一次循环,选出了一个最大值放到了最后,依次类推,每选出一个最大的数据放在最后,那么他们也就不需要再参与比较了没错吧。那么第二次循环的结束点就在arr.length-1再-循环次数,也就是将已经选出的数据排除在外不参与比较循环,减少计算机的运算量。
  3. 外层循环又减去了 1 。我们原程序是有几组数据就循环比较几次,为什么外层循环也可以少循环一次呢?很简单,当程序一直循环循环,直到只剩下两个数据时,也就是最小的数据和倒数第二小的数据,他们两个是不是只需要再比较一次就可以了呢?所以我们可以再减去 1 ,减少计算机运算量。

--------------------------------------------华丽的分割线----------------------------------------------------

然后我们来说一下这个略微不好理解的:

选择排序法:

选择排序法的原理:

  1. 所谓的选择排序,顾名思义,就是选择想要的数据,然后进行排序。

  2. 了解他的思路首先要知道他与冒泡法的区别在哪儿:冒泡法是依次两两相比选出大的放到后面,而选择排序则是选出小的放在开始,这就是他们的核心区别。

  3. 知道区别后我们在讲讲思路原理:首先我们自己默认第一个就是最小的,获取他对应的索引也就是0,然后拿这个索引对应的数据依次向后面的数据比较,如果后面有某一个数据比它还小,那么就获取这个数据对应的索引,然后继续拿着新获取的索引向后比较,直到结束。依次类推进行循环,依次选出最小的、第二小的、第三小的…实现我们需要的效果。思路合理开始执行!

基础代码(未优化):

<script>
        //选择排序数组
        var arr2 = [213,321,23,32,21,1];
        for (var j=0;j<=arr2.length-1;j++) {
            var min = j;
            for (var i = 0; i <= arr2.length - 1; i++) {
                if (arr2[min] > arr2[i + 1]) {
                    min = i + 1;
                }
            }
            if (min != j) {
                var middle2 = 0;
                middle2 = arr2[j];
                arr2[j] = arr2[min];
                arr2[min] =middle2;
            }
        }
        console.log(arr2);
    </script>

执行结果:
在这里插入图片描述
执行流程:
首先我们定义一个数组arr2.
同样是从内往外分析!!!

一、先看内层循环:

  1. 如同我们的思路一样,先默认第一个是最小的,定义一个变量 min ,也就是第一个数据的索引,此时可以先将他的值当做是0,别管 j 是什么。
  2. 然后我们进行循环判断:循环的起始就是第一个数值的索引到最后一个数值的索引,依次进行比较。进入循环,如果第一个数值大于后面的数值,则让我们默认的min存储这个比较小的数值对应的下标,如果没有到最后一个数据,就继续进行循环比较更改min中的值。
  3. 循环比较完毕之后,我们再看一下min中存的是不是我们默认的那个索引,如果不是,就进行数据交换操作。

二、再看外层循环:
我们内层每循环一次,都会得出一个最小的值,那么我们有几个数据就要循环几次,所以定义一个 j ,从0 — arr2.length-1,以此来得到我们想要的效果。

代码优化:

<script>
        //选择排序数组 优化
        var arr2 = [213,321,23,32,21,1];
        for (var j=0;j<=arr2.length-1 - 1 ;j++) {
            var min = j;
            for (var i = j ; i <= arr2.length - 1; i++) {
                if (arr2[min] > arr2[i + 1]) {
                    min = i + 1;
                }
            }
            if (min != j) {
                var middle2 = 0;
                middle2 = arr2[j];
                arr2[j] = arr2[min];
                arr2[min] =middle2;
            }
        }
        console.log(arr2);
    </script>

执行结果:
在这里插入图片描述
优化思路:
我们发现又有两处发生了变化,依然从内往外看:

  1. 我们发现内层循环i = 0;变成了i = j和min=0变成了min=j;这是为什么呢?很简单,我们每选出一个最小值放到前面,那么它是不是就不需要再参与循环比较了呢?因为它已经与其他的都进行比较过了,所以让他第一次从0开始,第二次从索引为1开始,第三次从索引为2开始…以此类推,这也是我们为什么要让 j 从0开始而不是从1开始,目的就是为了与内层循环匹配,方便我们优化。
  2. 我们发现外层循环又减去了一个 1 。与冒泡法的优化思路类似,我们每次循环都可以选出一个最小的值放到开始,当只剩下两个数据时,只需要再比较一次就可以了,所以可以再减去 1,减少一次循环让计算机轻松点程序更快一点 。

--------------------------------------------华丽的分割线----------------------------------------------------

总结:

我们学习这个主要是学习他的思考方式,多角度勤思考,利用自己所学的知识技巧,实现自己想要的项目效果。
就这两种算法而言,我更推荐选择排序这个算法,虽然他更复杂点,但是他的执行效率要远远高于冒泡排序,冒泡排序执行了很多次的数据交换,让程序十分的繁琐,没有选择更加的快捷方便,尽管每个程序员都是十分“懒”的,但是在执行效率这块儿要宁可自己多累一点,也要让计算机轻松一点,要学会对客户体验负责对自己的代码负责(切记!)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值