ES6的JavaScript数据结构实现之排序、搜索和随机算法
目的:ES6标准下的JS算法的一些实现代码。(作为记录和启发)
内容:排序、搜索和随机算法。冒泡排序,选择排序,插入排序,归并排序,快速排序,计数排序,桶排序,基数排序;顺序搜索,二分搜索,内插搜索;Fisher-Yates随机。(未完成,待继续)
所有源码在我的Github上(如果觉得不错记得给星鼓励我哦):ES6的JavaScript算法实现之排序、搜索和随机算法(分别在sorting、search、shuffle目录下)
一、基础算法
1、排序
1.1、冒泡排序
概念:冒泡排序比较所有相邻的两个项,如果第一个比第二个大,则交换他们。元素项向上移动至正确的顺序,就好像气泡升至表面一样。其复杂度是O(n2)。
1 | const Compare = { |
1.2、改进的冒泡排序
说明:如果从内循环减去外循环中已跑过的轮数,就可以避免内循环中所有不必要的比较。其复杂度是O(n2)。(嵌套了两个循环)
1 | const Compare = { |
1.3、选择排序
概念:选择排序算法是一种原址比较排序算法。选择排序大致的思路是找到数据结构中的最小值并将其放置在第一位,接着找到第二小的值并将其放置在第二位,以此类推。其复杂度是O(n2)。(嵌套了两个循环)
1 | const Compare = { |
1.4、插入排序
概念:插入排序每次排一个数组项,以此方式构建最后的排序数组。假定第一项已经排序了。接着,它和第二项进行比较–第二项是应该待在原位还是插入到第一项之前呢?这样,头两项就已正确排序,接着和第三项比较(它是该插入到第一、第二还是第三的位置呢),以此类推。(排序小型数组时,插入排序比选择排序和冒泡排序性能要好)
1 | const Compare = { |
1.5 归并排序
概念:归并排序是一种分而治之算法,其思想是将原始数组切分较小的数组,直到每个小数组只有一个位置,接着讲小数组归并成较大的数组,直到最后只有一个排序完毕的大数组。归并排序是第一个可以实际使用的排序算法,归并排序性能不错(比上三种排序好),其复杂度为O(nlog(n))。
1 | const Compare = { |
1.6 快速排序
概念:快速排序也许是最常用的排序算法了,它的复杂度为O(nlog(n)),且性能通常比其他复杂度为O(nlog(n))的排序算法好。快速排序也是使用分而治之的思想,将原始数组分为较小的数组(但它没有像归并排序那样将它们分割开)。思路:选择主元(pivot);划分(partition)操作;对划分后的小数组重复前两步操作,直至数组已完全排序。
1 | const Compare = { |
1.7 计数排序
概念:计数排序是一个分布式排序,使用已经组织好的辅助数据结构(称为桶),然后进行合并,得到排好序的数组。计数排序使用一个用来存储每个元素在原始数组中出现次数的临时数组。在所有元素都计数完成后,临时数组已拍好序并可迭代以构建排序后的结果数组。它是一个优秀的整数排序算法,时间复杂度为O(n+k),其中k是临时计数数组的大小;但是它确实需要更多的内存来存放临时数组。
1 | const Compare = { |
1.8 桶排序
概念:桶排序(箱排序)也是分布式排序算法,它将元素分为不同的桶(较小的数组),再使用一个简单的排序算法,例如插入排序,来对每个桶进行排序。然后,它将所有的桶合并为结果数组。
1 | const Compare = { |
1.9 基数排序
概念:基数排序是一个分布式排序算法,它根据数字的有效位或者基数将整数分布到桶中。基数是基于数组中值的记数制的。
1 | const Compare = { |
2、搜索算法
2.1 顺序搜索
概念:顺序或线性搜索是最基本的搜索算法。它的机制是将每一个数据结构中的元素和我们要找的元素作比较。(最低效)
1 | const DOES_NOT_EXIST = -1; |
2.2 二分搜索
二分搜索要求被搜索的数组已排序。步骤:1、选择数组中间值;2、如果选中值是待搜索值,那么算法执行完毕;如果带搜索值比选中值要小,则返回步骤1并在选中值左边的子数组中寻找(较小);4、 如果带搜索值比选中值要大,则返回步骤1并在选中值右边的子数组中寻找(较大)。
1 | const Compare = { |
2.3 内插搜索
概念:内插搜索是改良版的二分搜索。步骤:1、使用position公式选中一个值;2、如果选中值是待搜索值,那么算法执行完毕;如果带搜索值比选中值要小,则返回步骤1并在选中值左边的子数组中寻找(较小);4、 如果带搜索值比选中值要大,则返回步骤1并在选中值右边的子数组中寻找(较大)。
1 | const Compare = { |
3、随机算法
3.1、Fisher-Yates随机算法
概念:迭代数组,从最后一位开始并将当前位置和一个随机位置进行交换。这个随机位置比当前位置小。这样,这个算法可以保证随机过得位置不会再被随机一次(洗扑克牌的次数越多,随机效果越差)。
1 | function swap(array, a, b) { |