sort.js

JavaScript to achieve the ten common sorting algorithm library

  1 ;
  2 (function (global, factory) {
  3     // 兼容amd和cmd的写法
  4     // 基本的新式是 cmd ? cmd : amd ? amd : global || window
  5     typeof exports === ‘object‘ && typeof module !== ‘undefined‘ ? module.exports = factory() :
  6         typeof define === ‘function‘ && define.amd ? define(factory) :
  7         (global.PAS = factory());
  8 })(this, (function () {
  9     // 判断是否数组
 10     function isArray(arr) {
 11         return typeof Array.isArray === ‘function‘ ?
 12             Array.isArray(arr) :
 13             Object.prototype.toString.call(arr) === ‘[object Array]‘;
 14     }
 15
 16     // 交换两个元素
 17     function swap(v1, v2, context) {
 18         [context[v1], context[v2]] = [context[v2], context[v1]];
 19         return void 0;
 20     }
 21
 22     // 冒泡排序
 23     function bubble(arr) {
 24         let len = arr.length;
 25         for (let i = 0; i < len; i++) {
 26             for (let j = 0; j < len - 1 - i; j++) {
 27                 if (arr[j] > arr[j + 1]) {
 28                     swap(j, j + 1, arr)
 29                 }
 30             }
 31         }
 32         return arr;
 33     }
 34
 35     // 插入排序
 36     function insert(arr) {
 37         let len = arr.length;
 38         let pIndex, current; // 前一个元素的索引,当前元素的值
 39         for (let i = 1; i < len; i++) {
 40             pIndex = i - 1;
 41             current = arr[i];
 42
 43             // 依次把当前元素和前面的元素进行比较
 44             while (pIndex >= 0 && arr[pIndex] > current) {
 45                 // 比当前的元素大,向后移一位
 46                 arr[pIndex + 1] = arr[pIndex];
 47                 pIndex--;
 48             }
 49             // 插入当前元素到合适的位置
 50             arr[pIndex + 1] = current;
 51         }
 52         return arr;
 53     }
 54
 55     // 快速排序 -- 这个方法不改变原数组
 56     function quick(arr) {
 57         let len = arr.length;
 58
 59         if (len < 2) {
 60             return arr;
 61         }
 62
 63         let middleIndex = Math.floor(len / 2); // 中间元素的索引值
 64         let baseValue = arr.splice(middleIndex, 1); // 基准值
 65
 66         let left = []; // 保存小于基准值元素
 67         let right = []; // 保存大于或等于基准值元素
 68
 69         for (let i = 0; i < arr.length; i++) {
 70             if (arr[i] < baseValue) {
 71                 left.push(arr[i]);
 72             } else {
 73                 right.push(arr[i]);
 74             }
 75         }
 76         return quick(left).concat(baseValue, quick(right));
 77     }
 78
 79     // 选择排序
 80     function selection(arr) {
 81         let len = arr.length;
 82         let minIndex = 0; // 用于保存最小值的索引
 83
 84         for (let i = 0; i < len - 1; i++) {
 85             minIndex = i;
 86             // 遍历后面的元素和当前认为的最小值进行比较
 87             for (let j = i + 1; j < len; j++) {
 88                 if (arr[minIndex] > arr[j]) {
 89                     // 比认为的最小值小 交换索引
 90                     minIndex = j;
 91                 }
 92             }
 93             // 找到最小值和当前值交换
 94             if (minIndex !== i) {
 95                 swap(minIndex, i, arr);
 96             }
 97         }
 98         return arr;
 99     }
100
101     // 归并排序
102     function merge(arr) {
103         let len = arr.length;
104         if (len < 2) {
105             return arr;
106         }
107         let middleIndex = Math.floor(len / 2); // 获取中间元素的索引
108         let left = arr.slice(0, middleIndex); // 获取左半部分的元素
109         let right = arr.slice(middleIndex); // 获取右半部分的元素
110
111         let merges = function (left, right) {
112             // 保存结果的数组
113             let result = [];
114
115             while (left.length && right.length) {
116                 if (left[0] < right[0]) {
117                     result.push(left.shift())
118                 } else {
119                     result.push(right.shift())
120                 }
121             }
122
123             // 如果左半边还有元素
124             while (left.length) {
125                 result.push(left.shift());
126             }
127
128             // 如果右半边还有元素
129             while (right.length) {
130                 result.push(right.shift());
131             }
132
133             return result;
134         }
135
136         return merges(merge(left), merge(right));
137     }
138
139     // 希尔排序
140     function shell(arr) {
141         let len = arr.length,
142             temp,
143             gap = 1;
144
145         while (gap < len / 3) {
146             gap = gap * 3 + 1;
147         }
148
149         for (gap; gap > 0; gap = Math.floor(gap / 3)) {
150             for (let i = gap; i < len; i++) {
151                 temp = arr[i];
152                 for (var j = i - gap; j >= 0 && arr[j] > temp; j -= gap) {
153                     arr[j + gap] = arr[j];
154                 }
155                 arr[j + gap] = temp;
156             }
157         }
158         return arr;
159     }
160
161     // 堆排序
162     function heap(arr) {
163         let len = arr.length;
164
165         let heapify = function (
166             arr // 待排序的数组
167             , x // 元素的下标
168             , len // 数组的长度
169         ) {
170             let l = 2 * x + 1;
171             let r = 2 * x + 2;
172             let largest = x;
173
174             if (l < len && arr[l] > arr[largest]) {
175                 largest = l;
176             }
177
178             if (r < len && arr[r] > arr[largest]) {
179                 largest = r;
180             }
181
182             if (largest !== x) {
183                 swap(x, largest, arr);
184                 heapify(arr, largest, len);
185             }
186         }
187
188         for (let i = Math.floor(len / 2); i >= 0; i--) {
189             heapify(arr, i, len);
190         }
191
192         for (let i = len - 1; i >= 1; i--) {
193             swap(0, i, arr);
194             heapify(arr, 0, --len);
195         }
196         return arr;
197     }
198
199     // 基数排序
200     function radix(arr) {
201         const SIZE = 10;
202         let len = arr.length;
203         let buckets = [];
204         let max = Math.max.apply(null, arr); // 数组中的最大值
205         let maxLength = String(max).length; // 最大数字的长度
206
207         // 进行循环将桶中的数组填充成数组
208         for (let i = 0; i < SIZE; i++) {
209             buckets[i] = [];
210         }
211
212         // 进行循环--对数据进行操作--放桶的行为
213         for (let i = 0; i < maxLength; i++) {
214             // 第二轮循环是将数据按照个位数进行分类
215             for (let j = 0; j < len; j++) {
216                 let value = String(arr[j]);
217                 // 判断长度--进行分类
218                 if (value.length >= i + 1) {
219                     let num = Number(value[value.length - 1 - i]); // 依次的从右到左获取各个数字
220                     //放入对应的桶中
221                     buckets[num].push(arr[j]);
222                 } else {
223                     // 长度不满足的时候,就放在第一个桶中
224                     buckets[0].push(arr[i]);
225                 }
226             }
227             // 将原数组清空
228             arr.length = 0;
229
230             //这次循环是依次取出上面分类好的数组存放到原数组中
231             for (let j = 0; j < SIZE; j++) {
232                 // 获取各个桶的长度
233                 let l = buckets[j].length;
234                 // 循环取出数据
235                 for (let k = 0; k < l; k++) {
236                     arr.push(buckets[j][k]);
237                 }
238                 // 将对应的桶清空,方便下次存放数据
239                 buckets[j] = [];
240             }
241         }
242         return arr;
243     }
244
245     // 桶排序 -- 不改变原数组
246     function bucket(arr, size = 5) {
247         let len = arr.length;
248         if (len < 2) {
249             return arr;
250         }
251
252         // 获取最大值和最小值
253         const max = Math.max.apply(null, arr);
254         const min = Math.min.apply(null, arr);
255
256         // 计算出桶的数量  size是截距
257         const bucketCount = Math.floor((max - min) / size) + 1;
258         // 根据桶的个数创建指定长度的数组
259         const buckets = new Array(bucketCount);
260         // 将每个桶塞到大桶里面去
261         for (let i = 0; i < bucketCount; i++) {
262             buckets[i] = [];
263         }
264         // 利用映射函数将数据分配到各个桶里面去
265         for (let i = 0; i < arr.length; i++) {
266             // 逢size进1
267             let index = Math.floor((arr[i] - min) / size);
268             buckets[index].push(arr[i]);
269         }
270         //对每个桶中的数据进行排序--借助于快速排序算法
271         for (let i = 0; i < buckets.length; i++) {
272             buckets[i] = quick(buckets[i]);
273         }
274
275         // flatten数组--有点不足就是会将原数组中的String改变为Number
276         return buckets.join(‘,‘).split(‘,‘).filter(v => v !== ‘‘).map(Number);
277     }
278
279     // 计数排序
280     function count(arr) {
281         let index = 0;
282         let len = arr.length;
283         let min = Math.min.apply(null, arr); // 最小值
284         let max = Math.max.apply(null, arr); // 最大值
285         let result = []; // 结果数组
286
287         // 向新数组中填充0
288         for (let i = min; i <= max; i++) {
289             result[i] = 0;
290         }
291         // 把各个数组中对应的元素计数加一
292         for (let i = 0; i < len; i++) {
293             result[arr[i]]++;
294         }
295         // 按照计数的元素进行排序
296         for (let i = min; i <= max; i++) {
297             while (result[i]-- > 0) {
298                 arr[index++] = i;
299             }
300         }
301         return arr;
302     }
303
304     const PAS = {};
305
306     [
307         bubble,
308         insert,
309         quick,
310         selection,
311         merge,
312         shell,
313         heap,
314         radix,
315         bucket,
316         count
317     ].forEach(function (func) {
318         let name = func.name;
319         //增加层外包装,判断参数是不是数组
320         Object.defineProperty(PAS, name, {
321             get: function () {
322                 return function (args) {
323                     if (!isArray(args)) {
324                         throw new Error(‘the arguments of PAS.‘ + name + ‘ must be Array‘);
325                     }
326                     return func.call(null, args);
327                 }
328             },
329             configurable: true
330         })
331
332         // 在数组的原型上添加方法
333         Object.defineProperty(Array.prototype, name, {
334             get: function () {
335                 var vm = this;
336                 return function () {
337                     return func.call(vm, vm);
338                 }
339             },
340             configurable: true
341         })
342     })
343
344     return PAS;
345 }))
时间: 2025-01-14 13:21:47

sort.js的相关文章

JS的构造及其事件注意点总结

一:js的组成 ECMAscript bom dom 类型包括: number boolean  string undefined  object function 二:基本函数作用 parseInt(字符串)--作用:从字符串中提出整数,从左向右检查,只输出整数,如果碰到非整数,则自动停止检查. NAN--- NOT a number  不能拿两个NAN相比,总不相等. isNAN(参数 )函数--作用:判断是不是NAN  ---true ---false ==: 先把两边的东西转换成一样的类

jquery自带的排序方法(js也是)

jquery.sort() js.sort() <!DOCTYPE html> <html>   <head>     <meta charset="UTF-8">     <title></title>     <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>   </

前端网站资源精编!!

不要吝啬你的赞美喜欢就点个赞 目录: 1-------- 走进前端2-------- jQuery3-------- CSS4-------- Angularjs5-------- ES66-------- React7-------- 移动端API8-------- avalon9-------- Requriejs10-------- vue11-------- Seajs12-------- Less,sass13-------- Markdown14-------- D315------

看着看着就哭了的前端地址大全

原文地址:http://www.w3cfuns.com/notes/16438/db8e9e0bf80676f32b2cafb9b4932313.html 综合类 | 地址--- | --- 前端知识体系|http://www.cnblogs.com/sb19871023/p/3894452.html前端知识结构|https://github.com/JacksonTian/fksWeb前端开发大系概览|https://github.com/unruledboy/WebFrontEndStack

前端相关网址合集

综合类 | 地址--- | --- 前端知识体系--http://www.cnblogs.com/sb19871023/p/3894452.html前端知识结构--https://github.com/JacksonTian/fks免费的编程中文书籍索引--https://github.com/justjavac/free-programming-books-zh_CN智能社 - 精通JavaScript开发--http://study.163.com/course/introduction/2

jQWidgets笔记

http://www.jqwidgets.com/jquery-widgets-demo/ 常用: //设置列间距可调 $('#jqxGrid').jqxGrid({ columnsresize: false}); //获取是否可调值 var columnsresize = $('#jqxGrid').jqxGrid('columnsresize'); //数据绑定完成后事件 $("#jqxGrid").on("bindingcomplete", function

自己整理的一些前端资料

综合类 | 地址 --- | --- 前端知识体系|http://www.cnblogs.com/sb19871023/p/3894452.html 前端知识结构|https://github.com/JacksonTian/fks Web前端开发大系概览|https://github.com/unruledboy/WebFrontEndStack Web前端开发大系概览-中文版|http://www.cnblogs.com/unruledboy/p/WebFrontEndStack.html

Vue开发技巧

1 状态共享 随着组件的细化,就会遇到多组件状态共享的情况,Vuex当然可以解决这类问题,不过就像Vuex官方文档所说的,如果应用不够大,为避免代码繁琐冗余,最好不要使用它,今天我们介绍的是vue.js 2.6新增加的Observable API ,通过使用这个api我们可以应对一些简单的跨组件数据状态共享的情况. 随着组件的细化,就会遇到多组件状态共享的情况,Vuex当然可以解决这类问题,不过就像Vuex官方文档所说的,如果应用不够大,为避免代码繁琐冗余,最好不要使用它,今天我们介绍的是vue

mongodb - 关联字段

1,博客表结构  Blog.js var mongoose = require('mongoose') mongoose.connect('mongodb://localhost/test',{ useUnifiedTopology: true , useNewUrlParser: true}); var Schema = mongoose.Schema; var blogSchema = new Schema({ title:  String, author: String, body: