深入浅出“冒泡排序”

0.前言

冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。
它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。
走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端,故名。

正如百度百科中的所说,我们的冒泡排序是一种非常基础的一种算法,虽然在日常的工作中的使用的情况较少,但是由于其入门简单,逻辑清楚,还是非常适合初学者作为一个基础算法的入门,所以我们今天就一起来看一看,冒泡排序到底是怎么回事。

下面引用一下知乎用户可可的话术

想想有一群泡泡
其中一个泡泡跑到一个泡小妹说,小妹小妹你过来咱俩比比谁大,小妹说哇你好大,于是他跑到了泡小妹前面,又跟前面的一个泡大哥说,大哥,咱俩比比谁大呗。泡大哥看了他一眼他就老实了。这就是内层的for,那个泡泡跟每个人都比一次。
话说那个泡泡刚老实下来,另一个泡泡又开始跟别人比谁大了,这就是外层的for,每个泡泡都会做一次跟其他泡泡比个没完的事。

注意,以下代码部分由 JS 代码进行展示。

1.如何实现排序

既然我们想要进行排序,那么我们首先必须要有一个基础的数组,然而这个数组的情况可能会存在很多种,这里我们暂时只讨论最复杂的情况。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

</body>
<script type="text/javascript">
    // 声明一个最糟糕情况的数组
    var arr = [9,8,7,6,5,4,3,2,1];
</script>
</html>

注意,我在这里声明了一个非常糟糕的数组,也就是说,数组中的每一个内容都需要进行排序。

既然我们有了这么一个基础的数组,我们就可以正式开始对我们的内容进行排序了。

根据冒泡排序的思想,我们每一次循环,都将数组中最大的那个数字,放在数组的最后。

这样就可以保证我们的数组中,每次循环中的最大的那个都在后面,这样全部循环一次之后,我们的内容也就全部排序完毕了。

具体实现可以参考下面的图片。

第一次循环的时候,将数组中最大的那个内容放在程序的最后面。

这是我们第一次交换数组中内容,那么我们交换了几次呢?

我们总共交换了 8 次。

因为倒数第二次的时候,我们的 1 和 9 就已经排序完毕了,而最后的数字 9 不需要我们再交换一次,所以最后交换次数是 8 次。

而第二次交换呢?

我们同样需要将数组中最大的哪一个数字挪动到数组的最后一位,这个时候,我们需要挪动几次呢?

我们的交换次数相比于上面的情况再次减少一次,现在总共挪动了 7 次。

以此类推,我们可以想象出来,挪动的次数应该如同下面这张图一样。

我们的数组长度为 9。

我们外层的循环数,第一次将数组中最大的一位数字挪动到最后面,第二次挪动第二大的数字,第三次第三大数字,……,直到我们最后将所有的内容全部挪动完毕。

那么我们可以得出一个结论,我们需要挪动的次数是 数组的长度 - 1 次。

也就是说,我们可以去使用一个循环。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

</body>
<script type="text/javascript">
    var arr = [9,8,7,6,5,4,3,2,1];
    // 外层控制的循环的次数,看我这里需要循环几次
    for(var i = 0; i < arr.length - 1; i++){
        document.write('<br>');
    }
</script>
</html>

我们知道了我们这个数组需要循环几次,那么我们现在怎么控制我们需要在内部需要挪动几次呢?

这时候我们就要使用到内部的一层循环了。

我们可以在我们内层的循环中去控制我们的程序中间需要挪动几次。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

</body>
<script type="text/javascript">
    var arr = [9,8,7,6,5,4,3,2,1];
    // 外层控制的循环的次数,看我这里需要循环几次
    for(var i = 0; i < arr.length - 1; i++){
        // 内层控制数组内的循环次数
        for(var j = 0; j < arr.length -i -1; j++){
            document.write(arr + '<br>');
        }
        document.write('<br>');
    }

</script>
</html>

这时候我们就已经将我们的数组中每一个元素都能依次查找到了,可是我们的冒泡循环不是为了进行排序么?

这时候我们需要将大的数字挪动到后面。

那么我们该怎么做呢?

我们需要将两个元素进行交换,那么怎么交换呢?

我们可以再次声明一个变量,这样将两个数字进行交换了。

            // 进行内容的交换
            if(arr[j] > arr[j + 1]){
                var temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }

这时候我们将之前的所有的内容进行合并,我们可以通过双重循环,将前后的数字和在它后面的数字进行交换。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

</body>
<script type="text/javascript">
    var arr = [9,8,7,6,5,4,3,2,1];
    // 外层控制的循环的次数,看我这里需要循环几次
    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]){
                var temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
            document.write(arr + '<br>');
        }
        document.write('<br>');
    }

</script>
</html>

这样当我们循环结束之后,我们的数字也就正好全部替换完成了。

2.后续

其实我们现在表示的,是冒泡排序中最糟糕的情况,每一个数字都需要进行交换,但是我们日常工作中可能不是所有的数字都需要进行排列。

有一部分的数字已经是全部排序好的,这时候我们不需要完全进行排序。

那该怎么办呢?

其实我们可以去定义一个变量,专门用于记录当前这个循环是否进行了循环,如果当前内层循环中,一次交换也没有发生,那么是不是就证明我们这个序列已经排序完毕了呢?

这样我们就可以去判断我们的变量,去看看我们的循环是否可以结束。

今天时间有限,就不去书写具体的代码了,大家可以在网上简单搜索一下,冒泡排序优化,自己试着去看看,怎么去将这个东西进行优化吧!~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值