1. 程式人生 > >javascript quicksort quick sort, insertion sort 三分中值法 快速排序 插入排序 heapsort, mergesort

javascript quicksort quick sort, insertion sort 三分中值法 快速排序 插入排序 heapsort, mergesort

* 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