冒泡排序(Bubble Sort)算是前端最简单的算法,也是最经典的排序算法了。网上JavaScript版本的冒泡排序很多,今天用Vue实现一个动态的可视化冒泡排序。

01、JavaScript冒泡排序

冒泡排序原理也比较简单,就是相邻元素两两比较排序,把大的元素冒泡排序到后面,递归所有相邻元素组合完成排序。

1.1、原理

有一个无序数组:let arr = [100, 5, 6, 17, 3, 1],长度为len=6

  • 、从第一位元素100(0索引)开始,比较相邻arr[0]、arr[1]元素的大小,大的排后面,如果arr[0]>arr[1]则交换值位置。
  • 、如下图,依次相邻元素比较、交换,一轮完成后,最大元素就到了最右边了。这个过程中,最大的元素(最大的泡泡)就像冒泡一样到了末尾。

  • ③、然后继续对剩下的前面len-1=5个元素重复上述步骤,直到只剩下一个元素。这是一个递归的过程,递归到第一个元素,就完成了冒泡排序。

冒泡排序的动画过程如下图,排序过程很直观,一目了然,下一章节也实现一个跟好的。

1.2、JavaScript实现

经典冒泡排序算法,用两个for循环来实现所有元素的两两对比排序。统计了一下排序次数,一共比较了15次。冒泡排序的时间复杂度是O(n^2),这是最大值,最小为O(n)。

//经典冒泡排序算法
//从小到大冒泡排序
let arr = [100, 5, 6, 17, 3, 1];
let count=0; //计数器
function bubbleSort(arr) {
const len = arr.length;
let t;count=0;
for (let i = 0; i < len - 1; i++) {
for (let j = 0; j < len - i - 1; j++) {
count++;
//比较相邻两个元素
if (arr[j] > arr[j + 1]) {
//交换两个元素,大的往后排列
t = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = t;
}
}
}
return arr;
}
console.log(bubbleSort(arr),"比较次数:",count);
//[1, 3, 5, 6, 17, 100] '比较次数:' 15

上面代码中交换两个元素位置的时候,用了一个中间变量(t),可以改进一下。用一个解构赋值来交换值,就不用额外的一个中间变量(t)了。

let arr = [100, 5, 6, 17, 3, 1];
function bubbleSort(arr) {
const len = arr.length;
for (let i = 0; i < len - 1; i++) {
for (let j = 0; j < len - i - 1; j++) {
//比较相邻两个元素
if (arr[j] > arr[j + 1]) {
//用结构赋值进行交换
[arr[j], arr[j + 1]] = [arr[j+1], arr[j]];
}
}
}
return arr;
}
console.log(bubbleSort(arr));
//[1, 3, 5, 6, 17, 100]

02、Vue实现一个冒泡动画

用Vue来实现一个可视化的冒泡排序,用Vue就不用去操作Dom了,只需要要处理好排序过程即可,因此首先要对排序过程进行改造。

2.1、排序过程改造

上一章节的排序是连续执行,瞬间完成的。要实现可视化的排序效果,每一个排序步骤之间得有间隔,给过渡动画留时间。就需要把排序的每一个步骤拆开,可以单独控制执行。

  • 定义一个排序对象SortItem,包装待排序元素,用于可视化展示,属性包括排序值、泡泡大小、泡泡颜色。
  • 用上面的排序对象SortItem,生成排序对象集合,正式排序步骤中用该集合。方法的参数为排序元素字符串,空格隔开,如“9 100 6 17 3 1”。
//定义一个排序对象,包装待排序元素
function SortItem(n) {
this.value = n;
this.size = 30 + n + 'px'; //泡泡大小,初试大小30px
this.color = bubbleColor.default;
}
//生成排序对象集合,参数为排序元素字符串,如“9 100 6 17 3 1”
function generateSortItems(arrStr) {
let arrItems = [];
let arr = arrStr.trim().split(' ');
for (let i = 0; i < arr.length; i++) {
arrItems[i] = new SortItem(window.parseInt(arr[i]));
}
return arrItems;
}

泡泡列表展示效果如下:

  • 然后就是排序过程了,对排序对象集合进行遍历,把每一次排序操作包装成一个(闭包)函数,放到一个集合里,后面就可自定义调用执行了。
  • 先是用集合实现了一遍,发现这个场景用迭代器Generator更优雅,马上重构,上迭代器!每次迭代yield返回排序的函数。
//迭代器实现排序步骤的拆分
function* generateSortFunc(items) {
const len = items.length;
for (let i = 0; i < len - 1; i++) {
for (let j = 0; j < len - i - 1; j++) {
//迭代器返回的是一个(闭包)函数,为每一个排序步骤
yield () => {
//执行排序前重置泡泡颜色
resetColor(items);
//正在排序的泡泡元素高亮
items[j].color = bubbleColor.inprocess;
items[j + 1].color = bubbleColor.inprocess;
if (items[j].value > items[j + 1].value) {
[items[j], items[j + 1]] = [items[j + 1], items[j]];
}
}
}
//完成一轮排序,末尾泡泡元素标记为完成态颜色
items[len - i - 1].color = bubbleColor.completed;
}
}

什么是Generator?

  • 她是一个迭代器,返回一个遍历器对象,符合可迭代协议和迭代器协议,可用next()for(of)迭代。
  • 她是可控函数:内部代码可以自由控制暂停和继续执行。标准的函数是一次性执行完毕,直到末尾或return语句。而生成器的函数可以由yield暂停执行(交出控制权),next()恢复执行。
  • 她是一个状态机,封装了多个内部状态。
  • 她是异步任务管理容器,提供一种异步的实现方案。

Generator 使用一个特殊的函数语法function*(带星*号)创建生成器generator,调用生成器函数获得一个生成器对象,该对象的实例方法:

实例方法 描述
next() 恢复执行,返回一个由 yield表达式生成的值:{value: 1, done: false}
return(value?) 返回给定的值并结束生成器,可提前中止生成器。
throw() 向生成器抛出一个错误,生成器内部如没处理则会中止

2.2、可视化排序

接下来就不难了,排序的执行就是调用执行器的next()方法,如果返回对象的done属性为true,则表示迭代完成,否则继续迭代,执行排序函数。

//单步执行
play() {
let next = this.sortFunc.next();
if (next.done) {
this.sortItems.forEach(item => item.color = bubbleColor.completed);
this.stop();
}
else
next.value();
},
  • <li>元素来显示排序对象。
  • 移动动画用的Vue的<transition-group>组件来实现。
  • “单步执行”就是点击一次只执行一步,“自动执行”则会自动顺序执行。
  • 修改参数后需”重置“进行初始化。

手动单步执行效果:

自动执行或更多排序参数可以直接查看在线代码示例:掘金-代码(可视化冒泡),完整代码也在这里。

点击查看【juejin】


参考资料


️版权申明:版权所有@安木夕,本文内容仅供学习,欢迎指正、交流,转载请注明出处!原文编辑地址-语雀

JavaScript冒泡排序+Vue可视化冒泡动画的更多相关文章

  1. 冒泡动画按钮的简单实现(使用CSS3)

    冒泡动画按钮的简单实现(使用CSS3) 原始的参考文章是 http://tutorialzine.com/2010/10/css3-animated-bubble-buttons/ ,基本原理是利用了 ...

  2. Vue 中的动画特效

    Vue 中的动画特效 CSS 实现标签显隐 <!DOCTYPE html> <html lang="en"> <head> <meta c ...

  3. VUE:过渡&动画

    VUE:过渡&动画 vue动画的理解 1)操作css的 trasition 或 animation 2)vue会给目标元素添加/移除特定的class 3)过渡的相关类名 xxx-enter-a ...

  4. Vue过渡与动画

    通过 Vue.js 的过渡系统,可以在元素从 DOM 中插入或移除时自动应用过渡效果.Vue.js 会在适当的时机为你触发 CSS 过渡或动画,你也可以提供相应的 JavaScript 钩子函数在过渡 ...

  5. vue.js过度&动画、混入&插件

    1.vue  过度动画 1.过度 Vue 在插入.更新或者移除 DOM 时,提供多种不同方式的应用过渡效果.Vue 提供了内置的过渡封装组件,该组件用于包裹要实现过渡效果的组件. 语法格式: < ...

  6. Vue学习之动画小结(六)

    一.Vue中实现动画的方式:https://cn.vuejs.org/v2/guide/transitions.html Vue 在插入.更新或者移除 DOM 时,提供多种不同方式的应用过渡效果.包括 ...

  7. (尚014)Vue过渡与动画

    操作元素时有个过渡或动画的效果(渐变和移动的效果和放大缩小的效果) 过渡:trasition 动画:animation 1.vue动画的理解 1)操作css的trasition或animation(它 ...

  8. Vue过渡和动画效果展示(案例、GIF动图演示、附源码)

    前言 本篇随笔主要写了Vue过渡和动画基础.多个元素过渡和多个组件过渡,以及列表过渡的动画效果展示.详细案例分析.GIF动图演示.附源码地址获取. 作为自己对Vue过渡和动画效果知识的总结与笔记. 因 ...

  9. javascript实现汉诺塔动画效果

    javascript实现汉诺塔动画效果 当初以为不用html5也很简单,踩了javascript单线程的大坑后终于做出来了,没事可以研究下,对理解javascript的执行过程还是很有帮助的,代码很烂 ...

  10. javascript仿天猫加入购物车动画效果

    javascript仿天猫加入购物车动画效果   注意:首先需要声明的是:代码原思路不是我写的,是在网上找的这种效果,自己使用代码封装了下而已:代码中都有注释,我们最主要的是理解抛物线的思路及在工作中 ...

随机推荐

  1. SECS半导体设备通讯-2 HSMS通信标准

    一 HSMS通信标准概述 HSMS定义了使用 TCP/IP 作为物理传输媒质时的通信接口. HSMS使用TCP/IP流支持,提供了可靠的双向同步传输,可以用来作为SECS-I通信以及其他更高级的通信环 ...

  2. SECS半导体设备通讯-1 SECS的基本概念

    一 什么是SECS SECS(SEMI Equipment Communication Standard),半导体设备通讯标准. 此标准由SEMI (Semiconductor Equipment a ...

  3. BLS签名算法

    前言 [失踪人口回归 (*/ω\*)] 真的好久好久没有更新了,因为自己也还在找方向,但还是把新学的知识记录在博客里.今天要介绍的是BLS签名算法. 一.BLS签名算法简介 BLS签名算法[1]是由斯 ...

  4. 第一种方式:使用form表单将前端数据提交到servelt(将前端数据提交到servlet)

    第二种使用Ajax的形式将前台的数据传输到后台:https://blog.csdn.net/weixin_43304253/article/details/120335657 1.form表单 引入了 ...

  5. 自建流媒体如何录制视频。齐博x1齐博x2齐博x3齐博x4齐博x5齐博x6齐博x7齐博x8齐博x9齐博x10

    http://x1.eapis.site/ 先打开配置文件\conf\config.php 里边的内容大概如下,第一项是必须要配置的,换成你的网站域名网址.第二项,如果流媒体服务器配置了https证书 ...

  6. 齐博X1到底是个什么鬼?

    什么是齐博/齐博CMS之X1? 齐博X1是齐博软件基于thinkphp5开发的内容管理系统,拓展性非常强,后台一键升级,后台提供丰富的频道模块云市插件市场.风格市场.钩子市场,所有都是一键在线安装. ...

  7. linux下开机启动443程序无法访问解决方法

    前言:最近,有一个项目需要用到开机自动启动程序,所以就研究了一下,环境为redhat8,程序是node,使用forever来进行node程序的持久化,程序使用的是443端口,开启的是https 1.把 ...

  8. 一篇文章带你了解服务器操作系统——Linux简单入门

    一篇文章带你了解服务器操作系统--Linux简单入门 Linux作为服务器的常用操作系统,身为工作人员自然是要有所了解的 在本篇中我们会简单介绍Linux的特点,安装,相关指令使用以及内部程序的安装等 ...

  9. cameralink base 接口双通道任意图像数据源模拟

    设备说明 PCIe-CLS2000是基于PCIe 接口的2通道 camera link base接口图像模拟源,适用于图像数据源模拟.接收处理平台测试等场景. PCIe Gen2x4/x8 接口,支持 ...

  10. AIR32F103(五) FreeRTOSv202112核心库的集成和示例代码

    目录 AIR32F103(一) 合宙AIR32F103CBT6开发板上手报告 AIR32F103(二) Linux环境和LibOpenCM3项目模板 AIR32F103(三) Linux环境基于标准外 ...