├── .gitignore ├── bower.json ├── index.js ├── data.js ├── package.json ├── insertionsort.js ├── linklist.js ├── README.md ├── bucketsort.js ├── quicksort.js ├── example.js └── rowcol.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | bower_components 3 | dist 4 | .idea 5 | .tmp 6 | .log 7 | metadata 8 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ape-algorithm", 3 | "version": "0.0.7", 4 | "main": "index.js", 5 | "ignore": [ 6 | "**/.*", 7 | "node_modules", 8 | "bower_components", 9 | "test", 10 | "tests" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.quicksort = require('./quicksort');//快速排序 4 | exports.insertionsort = require('./insertionsort');//插入排序 5 | exports.bucketsort = require('./bucketsort');//桶排序 6 | exports.data = require('./data');//随机数据 7 | exports.rowcol = require('./rowcol');//行列互转 8 | 9 | -------------------------------------------------------------------------------- /data.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | ///////////////////////////////////////////////// 4 | // 产生数据 5 | ///////////////////////////////////////////////// 6 | 7 | var _this = this; 8 | 9 | /** 10 | * 产生随机整数随机数组 - 同步 11 | * 12 | * @param num Number 个数 13 | * @param min Number 最小值 14 | * @param max Number 最大值 15 | */ 16 | exports.randomData=function(n,min,max){ 17 | n=n||1000; 18 | min=min||0; 19 | max=max||100; 20 | 21 | var diff = max-min; 22 | var data = []; 23 | for(var i=0;i (http://blog.fens.me)", 13 | "license": "MIT", 14 | "main": "index.js", 15 | "dependencies": { 16 | "linklist": "0.0.3" 17 | }, 18 | "engines": { 19 | "node": ">=v0.10.5" 20 | }, 21 | "readmeFilename": "README.md", 22 | "gitHead": "cffc15b72ce68a7020dc70d31ed1756f142aa297", 23 | "scripts": { 24 | "test": "echo \"Error: no test specified\" && exit 1" 25 | }, 26 | "repository": { 27 | "type": "git", 28 | "url": "git://github.com/bsspirit/ape-algorithm.git" 29 | }, 30 | "bugs": { 31 | "url": "https://github.com/bsspirit/ape-algorithm/issues" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /insertionsort.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | ///////////////////////////////////////////////// 4 | // 插入排序 5 | ///////////////////////////////////////////////// 6 | 7 | var _this = this; 8 | 9 | /** 10 | * 普通数组插入排序 11 | * 12 | * @param arr Array 数字数组 13 | * @param dir asc升序、desc降序 14 | * 15 | * @example: 16 | * sort([1,4,2,5]) 17 | * sort([1,4,2,5],'asc') 18 | * sort([1,4,2,5],'desc') 19 | */ 20 | exports.sort = function (arr, dir) { 21 | dir = dir || 'asc'; 22 | if (arr.length == 0) return []; 23 | 24 | var i, j , x = 0; 25 | for (i = 1; i < arr.length; i++) { 26 | for (j = i; j > 0; j--) { 27 | if (arr[j] < arr[j - 1]) { 28 | x = arr[j]; 29 | arr[j] = arr[j - 1]; 30 | arr[j - 1] = x; 31 | } 32 | } 33 | } 34 | return dir=="desc"?arr.reverse():arr; 35 | } 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /linklist.js: -------------------------------------------------------------------------------- 1 | //https://github.com/joyent/node/blob/master/lib/_linklist.js 2 | //var L = require('_linklist'); 3 | // 4 | //var list ={}; 5 | //L.init(list); 6 | //console.log(L.isEmpty(list)); 7 | //L.append(list, "a"); 8 | //L.append(list, "b"); 9 | //L.append(list, "c"); 10 | //L.append(list, "d"); 11 | //console.log(L.isEmpty(list)); 12 | // 13 | //console.log(L.peek(list)); 14 | ////console.log(L.shift(list)); 15 | ////console.log(L.shift(list)); 16 | ////console.log(L.shift(list)); 17 | ////console.log(L.peek(list)); 18 | ////console.log(L); 19 | // 20 | //console.log(list); 21 | //console.log(list._idlePrev ); 22 | //console.log(list._idleNext ); 23 | 24 | 25 | var L = require('linklist'); 26 | var list = L.init(); 27 | L.append(list, {a:1}); 28 | L.append(list, {a:3}); 29 | L.append(list, {a:7}); 30 | L.append(list, {a:9}); 31 | 32 | var x={a:2}; 33 | 34 | var insert = false; 35 | L.traversal(list, function(item) { 36 | console.log(item.a); 37 | if(x.a 1 ? count : 10); 23 | 24 | // 判断最大值、最小值 25 | var min = arr[0], max = arr[0]; 26 | for (var i = 1; i < arr.length; i++) { 27 | min = min < arr[i] ? min : arr[i]; 28 | max = max > arr[i] ? max : arr[i]; 29 | } 30 | var delta = (max - min + 1) / count; 31 | // console.log(min+","+max+","+delta); 32 | 33 | //初始化桶 34 | var buckets = []; 35 | 36 | //存储数据到桶 37 | for (var i = 0; i < arr.length; i++) { 38 | var idx = Math.floor((arr[i] - min) / delta); // 桶索引 39 | 40 | if (buckets[idx]) {//非空桶 41 | var bucket = buckets[idx]; 42 | var insert = false;//插入标石 43 | L.reTraversal(bucket, function (item, done) { 44 | if (arr[i] <= item.v) {//小于,左边插入 45 | L.append(item, _val(arr[i])); 46 | insert = true; 47 | done();//退出遍历 48 | } 49 | }); 50 | if (!insert) { //大于,右边插入 51 | L.append(bucket, _val(arr[i])); 52 | } 53 | } else {//空桶 54 | var bucket = L.init(); 55 | L.append(bucket, _val(arr[i])); 56 | buckets[idx] = bucket; //链表实现 57 | } 58 | } 59 | 60 | var result = []; 61 | for (var i = 0, j = 0; i < count; i++) { 62 | L.reTraversal(buckets[i], function (item) { 63 | // console.log(i+":"+item.v); 64 | result[j++] = item.v; 65 | }); 66 | } 67 | return result; 68 | } 69 | 70 | //链表存储对象 71 | function _val(v) { 72 | return {v: v} 73 | } 74 | 75 | -------------------------------------------------------------------------------- /quicksort.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | ///////////////////////////////////////////////// 4 | // 快速排序 5 | ///////////////////////////////////////////////// 6 | 7 | var _this = this; 8 | 9 | /** 10 | * 普通数组快速排序 11 | * 12 | * @param arr Array 数字数组 13 | * @param dir asc升序、desc降序 14 | * 15 | * @example: 16 | * sort([1,4,2,5]) 17 | * sort([1,4,2,5],'asc') 18 | * sort([1,4,2,5],'desc') 19 | */ 20 | exports.sort=function(arr,dir){ 21 | dir=dir||'asc'; 22 | if (arr.length == 0) return []; 23 | 24 | var left = new Array(); 25 | var right = new Array(); 26 | var pivot = arr[0]; 27 | 28 | if(dir==='asc'){//升序 29 | for (var i = 1; i < arr.length; i++) { 30 | arr[i] < pivot ? left.push(arr[i]): right.push(arr[i]); 31 | } 32 | }else{//降序 33 | for (var i = 1; i < arr.length; i++) { 34 | arr[i] > pivot ? left.push(arr[i]): right.push(arr[i]); 35 | } 36 | } 37 | return _this.sort(left,dir).concat(pivot, _this.sort(right,dir)); 38 | } 39 | /** 40 | * 对象数组快速排序 41 | * 42 | * @param arr Array 对象数组 43 | * @param key string 用于排序的属性 44 | * @param dir asc升序、desc降序 45 | * 46 | * @example: 47 | * sort([{name:'b',id:12},{name:'c',id:21},{name:'a',id:2}],'id') 48 | * sort([{name:'b',id:12},{name:'c',id:21},{name:'a',id:2}],'id','asc') 49 | * sort([{name:'b',id:12},{name:'c',id:21},{name:'a',id:2}],'id','desc') 50 | */ 51 | exports.sortObj=function(arr,key,dir){ 52 | key=key||'id'; 53 | dir=dir||'asc'; 54 | if (arr.length == 0) return []; 55 | 56 | var left = new Array(); 57 | var right = new Array(); 58 | var pivot = arr[0][key]; 59 | var pivotObj = arr[0]; 60 | 61 | if(dir==='asc'){//升序 62 | for (var i = 1; i < arr.length; i++) { 63 | arr[i][key] < pivot ? left.push(arr[i]): right.push(arr[i]); 64 | } 65 | }else{//降序 66 | for (var i = 1; i < arr.length; i++) { 67 | arr[i][key] > pivot ? left.push(arr[i]): right.push(arr[i]); 68 | } 69 | } 70 | return _this.sortObj(left,key,dir).concat(pivotObj, _this.sortObj(right,key,dir)); 71 | } 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /example.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | ////////////////////////////////////////// 4 | // algorithm 5 | ////////////////////////////////////////// 6 | var algo = require('./index.js'); 7 | 8 | //普通数组快速排序 - 同步 9 | var arr = [23,12,11,43,54,43,2,12,66]; 10 | console.log(arr); 11 | console.log(algo.quicksort.sort(arr)); 12 | console.log(algo.quicksort.sort(arr,'desc')); 13 | 14 | //对象数组快速排序 - 同步 15 | var arrObj = [{name:'b',id:12},{name:'c',id:21},{name:'a',id:2}]; 16 | console.log(arrObj); 17 | console.log(algo.quicksort.sortObj(arrObj,'id')); 18 | console.log(algo.quicksort.sortObj(arrObj,'id','asc')); 19 | console.log(algo.quicksort.sortObj(arrObj,'id','desc')); 20 | 21 | //普通数组插入排序 - 同步 22 | var data = [ 7, 36, 65, 56, 33, 60, 110, 42, 42, 94, 59, 22, 83, 84, 63, 77, 67,101 ]; 23 | console.log(data); 24 | console.log(algo.insertionsort.sort(data)); 25 | console.log(algo.insertionsort.sort(data,'asc')); 26 | console.log(algo.insertionsort.sort(data,'desc')); 27 | 28 | //普通数组桶排序 - 同步 29 | var data = [ 7, 36, 65, 56, 33, 60, 110, 42, 42, 94, 59, 22, 83, 84, 63, 77, 67,101 ]; 30 | console.log(data); 31 | console.log(algo.bucketsort.sort(data,5)); 32 | console.log(algo.bucketsort.sort(data,10)); 33 | 34 | //产生随机数据 35 | var data = algo.data.randomData(1000*1000,1,100); 36 | console.log(data.length); 37 | 38 | ////////////////////////////////////////// 39 | //////产生随机数据 40 | ////////////////////////////////////////// 41 | //var data = algo.data.randomData(10*100,200,900); 42 | //var s1 = new Date().getTime(); 43 | //algo.quicksort.sort(data); 44 | //var s2 = new Date().getTime(); 45 | //algo.insertionsort.sort(data); 46 | //var s3 = new Date().getTime(); 47 | //algo.bucketsort.sort(data,700); 48 | //var s4 = new Date().getTime(); 49 | // 50 | //console.log("quicksort time: %sms",s2-s1); 51 | //console.log("insertion time: %sms",s3-s2); 52 | //console.log("bucket time: %sms",s4-s3); 53 | 54 | 55 | //////////////////////////////////////// 56 | ////行列互转 57 | //////////////////////////////////////// 58 | var data = [ 59 | { date: 20080102, x1: 1.5916, x2: 1.4916 }, 60 | { date: 20080103, x1: 2.5916, x2: 7.5916 }, 61 | { date: 20080104, x1: 3.5916, x2: 1.5916 } 62 | ]; 63 | var d2 = algo.rowcol.row2col(data); 64 | //console.log(d2); 65 | var d3 = algo.rowcol.col2row(d2); 66 | console.log(d3); 67 | var d4 = algo.rowcol.col2row2(d2); 68 | console.log(d4); 69 | 70 | 71 | //var d2 = algo.rowcol.row2col(data,'a','b'); 72 | //console.log(d2); 73 | //var d3 = algo.rowcol.col2row(d2,'a','b'); 74 | //console.log(d3); 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /rowcol.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | ///////////////////////////////////////////////// 4 | // 对JSON的数据行列转换 5 | ///////////////////////////////////////////////// 6 | 7 | var _this = this; 8 | 9 | /** 10 | * 列转行,时间复杂度O(n*m) 11 | * 12 | * @param data Array JSON数组 13 | * @prarm dcol string 字段列名 14 | * @prarm dcol string 数据列名 15 | * 16 | * @example: 17 | * data = [ 18 | * {"field": "date", "data": [20080102, 20080103, 20080104]}, 19 | * {"field": "x1", "data": [1.5916, 2.5916, 3.5916]}, 20 | * {"field": "x2", "data": [1.4916, 7.5916, 1.5916]} 21 | * ]; 22 | * col2row(data) 23 | * 24 | * @output 25 | * [ { date: 20080102, x1: 1.5916, x2: 1.4916 }, 26 | * { date: 20080103, x1: 2.5916, x2: 7.5916 }, 27 | * { date: 20080104, x1: 3.5916, x2: 1.5916 } ] 28 | */ 29 | exports.col2row = function (data,ccol, dcol) { 30 | ccol = ccol || 'field'; 31 | dcol = dcol || 'data'; 32 | 33 | var rowLen = data[0][dcol].length; 34 | var rows = []; 35 | for (var i = 0; i < rowLen; i++) { 36 | var row = {} 37 | for (var j = 0; j < data.length; j++) { 38 | row[data[j][ccol]] = data[j][dcol][i]; 39 | } 40 | rows.push(row); 41 | } 42 | return rows; 43 | } 44 | 45 | /** 46 | * 列转行, 时间复杂度O(n+m) 47 | * 48 | * @param data Array JSON数组 49 | * @prarm dcol string 字段列名 50 | * @prarm dcol string 数据列名 51 | */ 52 | exports.col2row2 = function (data, ccol, dcol) { 53 | ccol = ccol || 'field'; 54 | dcol = dcol || 'data'; 55 | 56 | var str = '' 57 | ,map = {} 58 | ,rowLen = 0 59 | ,i=0; 60 | 61 | for(i=0;i