javascript quicksort quick sort, insertion sort 三分中值法 快速排序 插入排序 heapsort, mergesort
阿新 • • 發佈:2019-02-05
* Arr.js
function Arr() { this.cmp = Arr.defaultCompareFunction; } Arr.prototype = []; Arr.fromArray = function(/* Array */ a) { var _this = new Arr(); for (var i = 0; i < a.length; i++) { _this.push(a[i]); } return _this; }; Arr.defaultCompareFunction = function(a, b) {return a - b;}; Arr.fromString = function (/* String */ s) /*:Arr */ { var _this = new Arr(); for (var i = 0; i < s.length; i++) { _this.push(s.charAt(i)); } return _this; }; Arr.prototype.exch = function(/*int*/ i, /*int */j) /* :Arr */ { if (i === j) {return;} var t = this[i]; this[i] = this[j]; this[j] = t; return this; }; Arr.prototype.shuffle = function() /*:Arr*/ { var m = this.length; while (m) { var i = Math.floor(m-- * Math.random()); this.exch(i, m); } return this; }; Arr.prototype.isSorted = function(/* function */ c) /* :boolean */ { c = c || this.cmp; for (var i = 1; i < this.length; i++) { if (c(this[i], this[i-1]) < 0) {return false;} } return true; }; Arr.prototype.shellsort = function(/* function */c) { this.cmp = c || Arr.defaultCompareFunction; var n = this.length, h = 1; while (h < Math.floor(n/3)) { h = 3 * h + 1; } while (h >= 1) { for (var i = h; i < n; i++) { for (var j = i; j >= h && this.cmp(this[j], this[j-h]) < 0; j -= h) { this.exch(j, j-h); } } h = Math.floor(h / 3); } return this; }; Arr.prototype._insertionsort = function(/* int */left, /* int */ right) /* :Arr */ { for (var p = left + 1; p <= right; p++) { var tmp = this[p]; for (var j = p; j > left && this.cmp(this[j-1], tmp) > 0; j--) { this[j] = this[ j-1 ]; } this[j] = tmp; } return this; }; Arr.prototype.insertionsort = function(/* function */ c) /* :Arr */ { this.cmp = c || Arr.defaultCompareFunction; return this._insertionsort(0, this.length-1); }; Arr.prototype._median3 = function(/* int */ left, /* int */right) /* :ElementType */ { var center = Math.floor((left+right)/2); if (this.cmp(this[left], this[center]) > 0) { this.exch(left, center); } if (this.cmp(this[left], this[right]) > 0) { this.exch(left, right); } if (this.cmp(this[center], this[right]) > 0) { this.exch(center, right); } /* this[left] <= this[center] <= this[right] */ this.exch(center, right-1); /* hide pivot */ return this[right-1]; /* return pivot */ }; Arr.CUTOFF = 3; Arr._qsort = function(/*Arr*/a, /*int */left, /* int */right) /* :Arr */ { var i, j; /* int */ var pivot; /* ElementType */ if (left + Arr.CUTOFF <= right) { pivot = a._median3(left, right); i = left; j = right -1; for (;;) { while (a.cmp(a[++i], pivot) < 0) {} while (a.cmp(a[--j], pivot) > 0) {} if (i < j) { a.exch(i, j); } else { break; } } a.exch(i, right-1); /* restore pivot */ Arr._qsort(a, left, i-1); Arr._qsort(a, i+1, right); } else { a._insertionsort(left, right); } }; Arr.prototype.qsort = function(/* function */ c) { this.cmp = c || Arr.defaultCompareFunction; Arr._qsort(this, 0, this.length-1); return this; }; Arr.prototype._percDown = function(/* Number */ i, /* Number */ n) { var leftChild = function(i) {return 2 * i +1;}, child = 0; for (var tmp = this[i]; leftChild(i) < n; i = child) { child = leftChild(i); if (child != n-1 && this.cmp(this[child+1], this[child]) > 0) child++; if (this.cmp(tmp, this[child]) < 0) this[i] = this[child]; else break; } this[i] = tmp; }; Arr.prototype.heapsort = function(/* function */ c) /* :Arr */ { this.cmp = c || Arr.defaultCompareFunction; /* build heap */ var n = this.length; for (var i = Math.floor(n/2); i >= 0; i--) { this._percDown(i, n); } for (i = n-1; i > 0; i--) { this.exch(0, i); /* Delete max */ this._percDown(0, i); } return this; }; /* lpos = start of left half, rpos = start of right half */ Arr._merge = function(/* Arr*/a, /*Arr*/ tmpArr, /*Number*/ lpos, /*Number*/rpos, /* Number */ rightEnd, /*function*/ c) { var leftEnd = rpos - 1, tmpPos = lpos, numElements = rightEnd - lpos + 1; /* main loop */ while (lpos <= leftEnd && rpos <= rightEnd) { if (c( a[lpos], a[rpos] ) <= 0) { tmpArr[tmpPos++] = a[lpos++]; } else { tmpArr[tmpPos++] = a[rpos++]; } } /* copy rest of first half */ while (lpos <= leftEnd) { tmpArr[tmpPos++] = a[lpos++]; } /* copy rest of second half */ while (rpos <= rightEnd) { tmpArr[tmpPos++] = a[rpos++]; } /* copy tmpArr back */ for (var i = 0; i < numElements; i++, rightEnd--) { a[rightEnd] = tmpArr[rightEnd]; } }; Arr._msort = function(/* Arr*/a, /*Arr*/t, /*Number*/l, /*Number*/r, /*function*/c) { var center = 0; if (l < r) { center = Math.floor((l + r)/2); Arr._msort(a, t, l, center, c); Arr._msort(a, t, center+1, r, c); Arr._merge(a, t, l, center+1, r, c); } }; Arr.prototype.mergesort = function(/* function */c) /* :Arr */ { this.cmp = c || Arr.defaultCompareFunction; var tmpArr = new Arr(), n = this.length; for (var i = 0; i < n; i++) { tmpArr.push(null); } Arr._msort(this, tmpArr, 0, n-1, this.cmp); tmpArr = null; return this; }; Arr.prototype.toString = function() { if (this.length<1) {return "[]"} var s = "["; for (var i = 0; i < this.length-1; i++) { s += this[i].toString() + ", "; } s += this[i].toString() + "]"; return s; }; exports.Arr = Arr;
* index.js
/** * Created by Mch on 2018/11/14. */ var Arr = require('./Arr').Arr; var a = Arr.fromArray([1,7,3,2,8,9,6,4,5,0]); console.log(a); // a._insertionsort(1, 5, Arr.defaultCompareFunction); var n = 5; while (n--) { a.qsort(); console.log(a.toString()); console.log(a.isSorted()); a.shuffle(); } var sa = Arr.fromString("shellsortexample"), strcmp = function(a, b) { for (var i = 0; i < a.length && i < b.length; i++) { if (a.charCodeAt(i) < b.charCodeAt(i)) { return -1; } else { return 1; } } return a.length === b.length ? 0 : a.length < b.length ? -1 : 1; }; sa.qsort(strcmp); console.log(sa.join('')); console.log(sa.isSorted(strcmp)); sa = Arr.fromString("quicksortexample"); sa.qsort(strcmp); console.log(sa.join('')); console.log(sa.isSorted(strcmp)); sa = Arr.fromString("thisisaheapsortexample"); sa.heapsort(strcmp); console.log(sa.join('')); console.log(sa.isSorted(strcmp)); sa = Arr.fromString("kerewamergesortdesu"); sa.mergesort(strcmp); console.log(sa.join('')); console.log(sa.isSorted(strcmp));
$ node index.js
Array {
'0': 1,
'1': 7,
'2': 3,
'3': 2,
'4': 8,
'5': 9,
'6': 6,
'7': 4,
'8': 5,
'9': 0,
cmp: [Function],
length: 10 }
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
true
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
true
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
true
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
true
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
true
aeeehlllmoprsstx
true
aceeiklmopqrstux
true
aaaeeehhiilmopprsssttx
true
adeeeeegkmorrrsstuw
true