热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

每日一算法之冒泡排序

程序数据结构算法在金庸武侠小说里,绝世高手的武功都是外功和内功的结合,你不仅需要能耍出亮瞎眼的招式,还得有能让招式发挥出真正威力的内功&#

程序=数据结构+算法

在金庸武侠小说里,绝世高手的武功都是外功和内功的结合,你不仅需要能耍出亮瞎眼的招式,还得有能让招式发挥出真正威力的内功;编程也是如此,我们在学习编程语言的语法、各种工具的使用的同时,应该要去好好学习数据结构和算法,了解一些底层的原理,这样才能功力深厚。

好了,开始进入主题吧!

对计算机存储的数据执行操作,排序是很常见的一种操作。一切按顺序来,多方便。
这里我们先创建一个数组类。使用ES6的语法(class),赶潮流嘛。

js代码如下:

class Arr {// 构造函数constructor(numElements) {// 存储的数据this.data = []// 记录数组下标this.index = 0// 生成数据的个数this.numElements = numElements// 初始化数组,数组长度为numElements,值为0-9for(let i = 0; i 0 && i % 10 == 0) {str += '\n'}}return str}// 将前后数据交换,用于之后的排序swap(arr, index1, index2) {let tmp = arr[index1]arr[index1] = arr[index2]arr[index2] = tmp}}

其中的setData()函数生成了存储在数组中的随机数字。Math.random()函数会生成[0,1)区间内的随机数字,然后我们将其再乘以(numElements + 1),这样就能生成1-100的随机数字集合了。这才是我们需要的数据。

测试一下:

const numElements = 100
const myNums = new Arr(numElements)
myNums.setData()
console.log(myNums.toString())

生成随机数据并按格式打印:

clipboard.png

好了,一个新的数组类已经创建完毕,接下来开始我们的冒泡排序了!

排序的核心思想是指对一组数据按照一定的顺序重新排列。重新排列时用到的技术是一组嵌套的for循环。外循环负责遍历数组的每一项,内循环负责比较元素。

冒泡排序算法是最慢的排序算法之一,但也是一种最容易实现的排序算法。

为什么叫冒泡排序呢,因为数据值就像气泡一样从数组的一端漂浮到另一端。假设正在将一组数字按照升序排序,较大的值会浮动到数组的右侧,而较小值会浮动到数组的左侧。因为该算法会多次在数组中移动,比较相邻的数据,如果左侧值大于右侧值则会将它们互换。

先来一个简单实例:

5 1 4 3 2

排序步骤:

1 4 3 2 5
1 3 2 4 5
1 2 3 4 5
至此,排序完成

接下来在刚刚创建的类中添加冒泡排序的代码:

sort() {for(let outer = this.data.length; outer > 1; outer--) {for(let inner = 0; inner this.data[inner+1]) {this.swap(this.data, inner, inner+1)}}}
}

测试代码:

const numElements = 10
const myNums = new Arr(numElements)
myNums.setData()
console.log(myNums.toString())
myNums.sort()
console.log(myNums.toString())

结果:

clipboard.png

代码非常简短,就是嵌套for循环,然后比较前后大小。
虽然这个算法是正常运行了,但是执行过程,数据是如何变化的呢,让我们一探究竟,这也能让我们真正理解冒泡排序算法,而不是只记得代码。

让我们加一个toString()吧!

sort() {for(let outer = this.data.length; outer > 1; outer--) {for(let inner = 0; inner this.data[inner+1]) {this.swap(this.data, inner, inner+1)}}console.log(this.toString())}}

结果:

clipboard.png

现在我们可以看到排序的具体过程了!

如何看代码的意思呢,我们拿[9,8,7,6,5,4,3,2,1,0]这个数组来说:

首先我们这里完全需要进行9次遍历,才能完全排好序。
我们先从数组的第一个值排起,需要比较9次
第一次 8,7,6,5,4,3,2,1,0,9 将9排到最后,现在不需要管9了,因为它是最大的,而且排到了最后,那么接下来就只需要比较8次了,再接着就是7,依次递减,直到为1,最后结束循环
7 6 5 4 3 2 1 0 8 9
6 5 4 3 2 1 0 7 8 9
5 4 3 2 1 0 6 7 8 9
4 3 2 1 0 5 6 7 8 9
3 2 1 0 4 5 6 7 8 9
2 1 0 3 4 5 6 7 8 9
1 0 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
就是如此,这是最坏的情况,而算法就应该考虑最坏的情况来编写,这样才能适应各种情况。

好了,冒泡排序算法暂时分享到这,后续更新其他算法,求关注!



推荐阅读
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 本文介绍了在wepy中运用小顺序页面受权的计划,包含了用户点击作废后的从新受权计划。 ... [详细]
  • 本文记录了在vue cli 3.x中移除console的一些采坑经验,通过使用uglifyjs-webpack-plugin插件,在vue.config.js中进行相关配置,包括设置minimizer、UglifyJsPlugin和compress等参数,最终成功移除了console。同时,还包括了一些可能出现的报错情况和解决方法。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • Webpack5内置处理图片资源的配置方法
    本文介绍了在Webpack5中处理图片资源的配置方法。在Webpack4中,我们需要使用file-loader和url-loader来处理图片资源,但是在Webpack5中,这两个Loader的功能已经被内置到Webpack中,我们只需要简单配置即可实现图片资源的处理。本文还介绍了一些常用的配置方法,如匹配不同类型的图片文件、设置输出路径等。通过本文的学习,读者可以快速掌握Webpack5处理图片资源的方法。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • 本文介绍了解决Facebook脸书面试题中插入区间的方法,通过模拟遍历的方式判断当前元素与要插入元素的关系,找到插入点并将新区间插入。同时对算法的时间复杂度和空间复杂度进行了分析。 ... [详细]
  • MySQL中的MVVC多版本并发控制机制的应用及实现
    本文介绍了MySQL中MVCC的应用及实现机制。MVCC是一种提高并发性能的技术,通过对事务内读取的内存进行处理,避免写操作堵塞读操作的并发问题。与其他数据库系统的MVCC实现机制不尽相同,MySQL的MVCC是在undolog中实现的。通过undolog可以找回数据的历史版本,提供给用户读取或在回滚时覆盖数据页上的数据。MySQL的大多数事务型存储引擎都实现了MVCC,但各自的实现机制有所不同。 ... [详细]
  • 上图是InnoDB存储引擎的结构。1、缓冲池InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。因此可以看作是基于磁盘的数据库系统。在数据库系统中,由于CPU速度 ... [详细]
author-avatar
关注丑开
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有