sort.js
JavaScript to achieve the ten common sorting algorithm library 1 ;
(function (global, factory) {
// 兼容amd和cmd的写法
// 基本的新式是 cmd ? cmd : amd ? amd : global || window
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.PAS = factory());
})(this, (function () {
// 判断是否数组
function isArray(arr) {
return typeof Array.isArray === 'function' ?
Array.isArray(arr) :
Object.prototype.toString.call(arr) === '[object Array]';
} // 交换两个元素
function swap(v1, v2, context) {
[context[v1], context[v2]] = [context[v2], context[v1]];
return void 0;
} // 冒泡排序
function bubble(arr) {
let len = arr.length;
for (let i = 0; i < len; i++) {
for (let j = 0; j < len - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
swap(j, j + 1, arr)
}
}
}
return arr;
} // 插入排序
function insert(arr) {
let len = arr.length;
let pIndex, current; // 前一个元素的索引,当前元素的值
for (let i = 1; i < len; i++) {
pIndex = i - 1;
current = arr[i]; // 依次把当前元素和前面的元素进行比较
while (pIndex >= 0 && arr[pIndex] > current) {
// 比当前的元素大,向后移一位
arr[pIndex + 1] = arr[pIndex];
pIndex--;
}
// 插入当前元素到合适的位置
arr[pIndex + 1] = current;
}
return arr;
} // 快速排序 -- 这个方法不改变原数组
function quick(arr) {
let len = arr.length; if (len < 2) {
return arr;
} let middleIndex = Math.floor(len / 2); // 中间元素的索引值
let baseValue = arr.splice(middleIndex, 1); // 基准值 let left = []; // 保存小于基准值元素
let right = []; // 保存大于或等于基准值元素 for (let i = 0; i < arr.length; i++) {
if (arr[i] < baseValue) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
return quick(left).concat(baseValue, quick(right));
} // 选择排序
function selection(arr) {
let len = arr.length;
let minIndex = 0; // 用于保存最小值的索引 for (let i = 0; i < len - 1; i++) {
minIndex = i;
// 遍历后面的元素和当前认为的最小值进行比较
for (let j = i + 1; j < len; j++) {
if (arr[minIndex] > arr[j]) {
// 比认为的最小值小 交换索引
minIndex = j;
}
}
// 找到最小值和当前值交换
if (minIndex !== i) {
swap(minIndex, i, arr);
}
}
return arr;
} // 归并排序
function merge(arr) {
let len = arr.length;
if (len < 2) {
return arr;
}
let middleIndex = Math.floor(len / 2); // 获取中间元素的索引
let left = arr.slice(0, middleIndex); // 获取左半部分的元素
let right = arr.slice(middleIndex); // 获取右半部分的元素 let merges = function (left, right) {
// 保存结果的数组
let result = []; while (left.length && right.length) {
if (left[0] < right[0]) {
result.push(left.shift())
} else {
result.push(right.shift())
}
} // 如果左半边还有元素
while (left.length) {
result.push(left.shift());
} // 如果右半边还有元素
while (right.length) {
result.push(right.shift());
} return result;
} return merges(merge(left), merge(right));
} // 希尔排序
function shell(arr) {
let len = arr.length,
temp,
gap = 1; while (gap < len / 3) {
gap = gap * 3 + 1;
} for (gap; gap > 0; gap = Math.floor(gap / 3)) {
for (let i = gap; i < len; i++) {
temp = arr[i];
for (var j = i - gap; j >= 0 && arr[j] > temp; j -= gap) {
arr[j + gap] = arr[j];
}
arr[j + gap] = temp;
}
}
return arr;
} // 堆排序
function heap(arr) {
let len = arr.length; let heapify = function (
arr // 待排序的数组
, x // 元素的下标
, len // 数组的长度
) {
let l = 2 * x + 1;
let r = 2 * x + 2;
let largest = x; if (l < len && arr[l] > arr[largest]) {
largest = l;
} if (r < len && arr[r] > arr[largest]) {
largest = r;
} if (largest !== x) {
swap(x, largest, arr);
heapify(arr, largest, len);
}
} for (let i = Math.floor(len / 2); i >= 0; i--) {
heapify(arr, i, len);
} for (let i = len - 1; i >= 1; i--) {
swap(0, i, arr);
heapify(arr, 0, --len);
}
return arr;
} // 基数排序
function radix(arr) {
const SIZE = 10;
let len = arr.length;
let buckets = [];
let max = Math.max.apply(null, arr); // 数组中的最大值
let maxLength = String(max).length; // 最大数字的长度 // 进行循环将桶中的数组填充成数组
for (let i = 0; i < SIZE; i++) {
buckets[i] = [];
} // 进行循环--对数据进行操作--放桶的行为
for (let i = 0; i < maxLength; i++) {
// 第二轮循环是将数据按照个位数进行分类
for (let j = 0; j < len; j++) {
let value = String(arr[j]);
// 判断长度--进行分类
if (value.length >= i + 1) {
let num = Number(value[value.length - 1 - i]); // 依次的从右到左获取各个数字
//放入对应的桶中
buckets[num].push(arr[j]);
} else {
// 长度不满足的时候,就放在第一个桶中
buckets[0].push(arr[i]);
}
}
// 将原数组清空
arr.length = 0; //这次循环是依次取出上面分类好的数组存放到原数组中
for (let j = 0; j < SIZE; j++) {
// 获取各个桶的长度
let l = buckets[j].length;
// 循环取出数据
for (let k = 0; k < l; k++) {
arr.push(buckets[j][k]);
}
// 将对应的桶清空,方便下次存放数据
buckets[j] = [];
}
}
return arr;
} // 桶排序 -- 不改变原数组
function bucket(arr, size = 5) {
let len = arr.length;
if (len < 2) {
return arr;
} // 获取最大值和最小值
const max = Math.max.apply(null, arr);
const min = Math.min.apply(null, arr); // 计算出桶的数量 size是截距
const bucketCount = Math.floor((max - min) / size) + 1;
// 根据桶的个数创建指定长度的数组
const buckets = new Array(bucketCount);
// 将每个桶塞到大桶里面去
for (let i = 0; i < bucketCount; i++) {
buckets[i] = [];
}
// 利用映射函数将数据分配到各个桶里面去
for (let i = 0; i < arr.length; i++) {
// 逢size进1
let index = Math.floor((arr[i] - min) / size);
buckets[index].push(arr[i]);
}
//对每个桶中的数据进行排序--借助于快速排序算法
for (let i = 0; i < buckets.length; i++) {
buckets[i] = quick(buckets[i]);
} // flatten数组--有点不足就是会将原数组中的String改变为Number
return buckets.join(',').split(',').filter(v => v !== '').map(Number);
} // 计数排序
function count(arr) {
let index = 0;
let len = arr.length;
let min = Math.min.apply(null, arr); // 最小值
let max = Math.max.apply(null, arr); // 最大值
let result = []; // 结果数组 // 向新数组中填充0
for (let i = min; i <= max; i++) {
result[i] = 0;
}
// 把各个数组中对应的元素计数加一
for (let i = 0; i < len; i++) {
result[arr[i]]++;
}
// 按照计数的元素进行排序
for (let i = min; i <= max; i++) {
while (result[i]-- > 0) {
arr[index++] = i;
}
}
return arr;
} const PAS = {}; [
bubble,
insert,
quick,
selection,
merge,
shell,
heap,
radix,
bucket,
count
].forEach(function (func) {
let name = func.name;
//增加层外包装,判断参数是不是数组
Object.defineProperty(PAS, name, {
get: function () {
return function (args) {
if (!isArray(args)) {
throw new Error('the arguments of PAS.' + name + ' must be Array');
}
return func.call(null, args);
}
},
configurable: true
}) // 在数组的原型上添加方法
Object.defineProperty(Array.prototype, name, {
get: function () {
var vm = this;
return function () {
return func.call(vm, vm);
}
},
configurable: true
})
}) return PAS;
}))
sort.js的更多相关文章
- js sort tricks All In One
js sort tricks All In One js 排序技巧 const arr = [ { label: 'False 1 ', disabled: false, }, { label: 'F ...
- JS的构造及其事件注意点总结
一:js的组成 ECMAscript bom dom 类型包括: number boolean string undefined object function 二:基本函数作用 parseInt ...
- 前端的重要部分js
js用来实现页面的动态效果. js的特点:1.是客户端语言,客户端进行解释执行. 2.是一种脚本语言 3.是一种基于对象的语言,不用定义类和实例化对象,直接使用类即可 4.js前端和后端都可以做 js ...
- jquery自带的排序方法(js也是)
jquery.sort() js.sort() <!DOCTYPE html> <html> <head> <meta charset=&qu ...
- github上最全的资源教程-前端涉及的所有知识体系
前面分享了前端入门资源汇总,今天分享下前端所有的知识体系. 个人站长对个人综合素质要求还是比较高的,要想打造多拉斯自媒体网站,不花点心血是很难成功的,学习前端是必不可少的一个环节, 当然你不一定要成为 ...
- 使用 jquery 开发用户通讯录
由于开发需求,需要做一个通讯录界面,点击右侧首字母菜单,列表会将对应字母列表成员滑动至顶部,效果如下图(包括点击事件+长按事件): 1.需求分析 (1)首先,我们需要把数据里用户名转换为首拼,然后归类 ...
- Excel数组排序+图片统一大小
Sub 图片调整合适大小() ' Debug.Print ActiveWorkbook.Name 图片显示比例 = 0.9 '1为顶满单元格 Dim wb As Workbook, sh As Wor ...
- 【JavaScript&jQuery】前端资源大全
综合类 综合类 地址 前端知识体系 http://www.cnblogs.com/sb19871023/p/3894452.html 前端知识结构 https://github.com/Jackson ...
- 移动端的拖拽排序在react中实现 了解一下
最近做一个拖拽排序的功能找了好几个有一个步骤简单,结合redux最好不过了,话不多说上代码 第一步: npm install react-draggable-tags --save 第二步 sort. ...
随机推荐
- go语言之进阶篇字符串转换
1.字符串转换 示例: package main import ( "fmt" "strconv" ) func main() { //转换为字符串后追加到字节 ...
- Centos7 搭建lnmp环境 (centos7+nginx+MySQL5.7.9+PHP7)
阿里云一台服务器出现问题! 我估计是一键安装包环境的原因,所以打算重新搭建下环境! 首先,当然是先做好快照!安全第一! 对系统盘做更换系统操作,装上纯净版的centos. 装好后,进入系统 一.挂载数 ...
- SQL Server 损坏修复 之一 常见错误解读
SQL Server 对数据库损坏的错误类型做了细化,在此对几个典型的错误作一下介绍. 错误信息是:“在文件 '%ls'中.偏移量为 %#016I64x 的位置执行 %S_MSG 期间,操作系统已经向 ...
- [置顶] Hadoop2.2.0中HDFS的高可用性实现原理
在Hadoop2.0.0之前,NameNode(NN)在HDFS集群中存在单点故障(single point of failure),每一个集群中存在一个NameNode,如果NN所在的机器出现了故障 ...
- 集成学习总结 & Stacking方法详解
http://blog.csdn.net/willduan1/article/details/73618677 集成学习主要分为 bagging, boosting 和 stacking方法.本文主要 ...
- express next function
nodejs 里面的next()这个函数调用的作用是什么呢? var express = require('express'); var app = express(); var myLogger = ...
- Spark参数设置的方式
可以通过以下几种方式设置: 1)bin/spark-submit 可以直接读取conf/spark-defaults.conf文件 每一行为一个key和valuespark.master ...
- 鼠标上下滚动支持combobox选中
首先需要jquery插件来支持: 1.代码SVN检出https://github.com/jquery/jquery-mousewheel 2.点击这里下载jquery.mousewheel.zip ...
- javascript捕获事件event
var e = e ? e : window.event; window.event ? window.event.cancelBubble = true : e.stopPropagation(); ...
- 离线LCA学习
题目1 : 近期公共祖先·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描写叙述 上上回说到,小Hi和小Ho用很拙劣--或者说粗糙的手段山寨出了一个奇妙的站点,这个站点能 ...