首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >前端学习数据结构与算法系列(五):冒泡排序的理解与实现

前端学习数据结构与算法系列(五):冒泡排序的理解与实现

作者头像
一只图雀
发布2020-05-07 10:52:08
6840
发布2020-05-07 10:52:08
举报
文章被收录于专栏:图雀社区图雀社区图雀社区

本文由图雀社区认证作者 神奇的程序员 写作而成,图雀社区将连载其前端学习数据结构与算法系列,点击阅读原文查看作者的掘金链接,感谢作者的优质输出,让我们的技术世界变得更加美好?

前言

当面试官问你什么是排序算法?请你用JavaScript实现一个简单的冒泡排序,如果你没掌握,就会被问住。

本文采用图文的方式讲解冒泡排序的特点,分步骤讲解js的实现思路以及相对应的代码,欢迎各位感兴趣的开发者阅读本文?

概念

从序列的最右边开始比较相邻两个数字的大小,再根据结果交换两个数字的位置,重复这一操作的算法即冒泡排序

特点

  • 从序列的末尾开始比较相邻两个数字的大小
  • 如果比较的数据比左边相邻的数据小,则左移当前比较的数据。
  • 直至当前比较数据的位置等于当前比较次数时,则一轮结束。
  • 比较完一轮后,如果当前轮数不等于序列的长度,则继续从末尾开始比较。

图解示例

如图所示,将下列数字按从小到大的顺序进行排列。

  • 从数据的末尾开始比较相邻两个数字的大小
  • 比较后,发现6<7,故交换位置。
  • 完成后,将6与相邻的数字4进行比较,6>4,故不交换位置
  • 完成后,将4与相邻的数字8进行比较,4<8,故交换位置
  • 重复同样的操作进行比较,直到当前比较的值到数据的最左边为止。
  • 不断对数字进行交换,直到当前比较的数字到了最左边,无相邻数据可比较,序列中最小的数字就会移动到最左边。
  • 继续下一轮排序,从数据的末尾继续进行比较,直到比较到数据的第2个位置为止。
  • 当比较到数据的左边第2个位置时,序列中第2小的数字也就到达了指定位置。
  • 重复上述操作,直到当前比较的数字的位置为当前比较的次数,即排序完成。

实现思路

  • 声明一个函数,参数为一个数组
  • 初始化比较轮数为1
  • 对数组进行遍历
  • 在循环中获取当前比较值在数组中的的下标:数组长度 - 当前循环次数
  • 在循环中获取当前比较值左侧相邻值在数组中的下标:数组长度 - (当前循环的次数+2)
  • 得到下标后,分别获取当前比较值和与之左侧相邻的值
  • 判断当前比较值的数组下标是否等于当前轮数
  • 如果相等则轮数自增1,如果当前轮数不等于数组长度则让循环继续执行
  • 如果不相等,则比较当前值与左侧相邻值的大小,如果当前值<左侧相邻值,则进行位置交换
  • 如果当前轮数等于数组长度,循环结束,返回排序好的数组。

接下来,我们用JavaScript根据实现思路来实现下冒泡排序。

const bubbleSort = function (arr) {
    // 比较的轮数
    let round = 1;
    for (let i = 0; i < arr.length;i++){
        // 当前比较值的位置 = 数组长度 - 当前循环的次数(i从0开始,所以需要+1)
        const compareIndex = arr.length-(i+1);
        // 与当前比较值左侧相邻值的位置 = 数组长度 - (当前循环的次数+2)
        const leftNeighborIndex = arr.length-(i+2);
        // 获取当前比较的值
        const compareVal = arr[compareIndex];
        // 获取与之相邻的左侧值
        const leftNeighborVal = typeof arr[leftNeighborIndex] !=="undefined"?arr[leftNeighborIndex]:"";
        // 如果当前比较值的位置等于轮数(因为轮数是从1开始的,数组下标是从0开始的,所以需要-1)时则一轮结束
        if(compareIndex===round-1){
            console.log(`第 ${round}轮结束: ${arr},共比较 ${i}次`);
            // 轮数增加
            round ++;
            // 如果当前轮数不等于数组长度则循环继续
            if(round!==arr.length){
                i = -1;
            }
        } else{
            // 比较当前值与左侧相邻值的大小
            if(compareVal<leftNeighborVal){
                // 交换位置,使用结构赋值实现。[array[index1],array[index2]] = [array[index2],array[index1]]
                [arr[compareIndex],arr[leftNeighborIndex]] = [arr[leftNeighborIndex],arr[compareIndex]];
            }
        }
    }
    return arr;
};

// 声明一个乱序
const dataArr = [5,8,2,7,9,1,10,0];
// 调用函数
console.log(bubbleSort(dataArr));

执行结果

双层冒泡和单层冒泡的比较

本来对我的单层冒泡很自信,认为我写的单层效率肯定比双层的效率高,结果啪啪打脸,我拿我写的和网上的双层循环在控制台跑了一遍,才发现我写的简直就是垃圾。

为什么单层的效率低

当我疑惑我的效率为啥慢的时候,我朋友给了我结论,好吧,是我太菜了。

写在最后

* 文中使用的图片源自《我的第一本算法书》,如若侵权,请联系图雀社区公众号小编,作者立即删除相关图片。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 图雀社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 概念
  • 特点
  • 图解示例
  • 实现思路
  • 双层冒泡和单层冒泡的比较
    • 为什么单层的效率低
    • 写在最后
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档