在原型数组上实现quicksort递归函数

时间:2017-08-23 14:25:12

标签: javascript arrays algorithm sorting ecmascript-6

Array.prototype.quickSort = function () {
let self = this;
let len = self.length;
let pivot_pos;
let result = []
if (len < 2) {
  return self
}
pivot_pos = self.partition();
let left = self.splice(0, pivot_pos),
right = self.splice(0);


error --> left.quickSort();
error --> right.quickSort();

console.log(left);
console.log(right);
//right_pivot_pos = right.partition();

return this;
}

Array.prototype.partition = function () {
    let arr = this;
    let pivot_pos = Math.floor((arr.length-1)/2);
let last_small = arr[0]
let i;
//console.log(`before this[0] ${this[0]} and before this[pivot_pos] 
${this[pivot_pos]}`);
[arr[pivot_pos], arr[0]] = [arr[0], arr[pivot_pos]];
//console.log(`this[0] ${this[0]} and this[pivot_pos] 
${this[pivot_pos]}`);

 for (i=1;i<arr.length; i++) {
   if(arr[i]<arr[0]) {
     //[this[i], this[num]] = [this[num], this[i]];
     let tmp = arr[last_small];
     arr[last_small] = arr[i];
     arr[i] = tmp;
     last_small++;
     }
   }
 [arr[0], arr[last_small-1]] = [arr[last_small-1], arr[0]];
 return last_small;
}

let sandbox = [1,2,6,5,4,3,7,9];
console.log(sandbox.quickSort());

我无法调用left.quickSort();和right.quickSort(); JavaScript堆内存不足...编写此代码的替代方法是什么?我在git上在线浏览了一些,但它与计算运行功能的成本不同。

2 个答案:

答案 0 :(得分:2)

我在下面列出了代码的固定版本。最重要的修复包括:

  • partition中,变量last_small包含元素的值,但稍后在循环中用作索引。
  • partition中,您总是将元素与索引0进行比较而不是移动的枢轴元素。
  • quicksort函数保持对2元素数组的分区和排序。因此内存溢出异常。
  • 完成后不会重建原始数组。请注意,splice会修改原始数组。

Array.prototype.quickSort = function () {
    var self = this;

    if ( self.length < 2 ) {
        return self
    }

    var pivot_pos = self.partition();

    if ( self.length > 2 ) {
        var left = self.splice( 0, pivot_pos );
        var right = self.splice( 0 );

        self.splice.apply( self, [ 0, 0 ].concat( right.quickSort() ) );
        self.splice.apply( self, [ 0, 0 ].concat( left.quickSort() ) );
    }

    return this;
};

Array.prototype.swap = function (i, j) {
    var tmp = this[i];
    this[i] = this[j];
    this[j] = tmp;
};

Array.prototype.partition = function () {
    var self = this;
    var pivot_pos = Math.floor( (self.length - 1) / 2 );
    var last_small_i = 0;

    self.swap( last_small_i, pivot_pos );

    for ( var i = 1; i < self.length; i++ ) {
        if ( self[ i ] < self[ last_small_i ] ) {
            self.swap( last_small_i, i );
            last_small_i++;
            
            if(i != last_small_i) {
                self.swap( last_small_i, i );
            }
        }
    }

    return last_small_i;
};

var sandbox = [ 1, 10, 6, 5, 4, 3, 7, 9 ];
console.log( sandbox.quickSort() );

答案 1 :(得分:1)

Array.prototype.swap = function (i, j) {
    var tmp = this[i];
    this[i] = this[j];
    this[j] = tmp;
};

Array.prototype._quicksort = function(A, i, j) {
    if (i >= j) {
        return;
    }
    if (i+1 == j) {
        if (A[i] > A[j]) {
            A.swap(i,j);
        }
        return;
    }

    var p = Math.floor((i+j)/2);
    A.swap(i, p);

    var l = i;
    var r = j;
    while (l <= r) {
        if (A[l] <= A[i]) {
            l++;
        } else if (A[r] > A[i]) {
            r--;
        } else {
            A.swap(l, r);
            l++;
            r--;
        }
    }

    p = l-1;
    A.swap(i, p);

    Array.prototype._quicksort(A, i, p-1);
    Array.prototype._quicksort(A, p+1, j);
}

Array.prototype.quickSort = function () {
    Array.prototype._quicksort(this, 0, this.length-1);
    return this;
};

var A = [ 1, 10, 6, 2, 8, 5, 4, 3, 7, 9 ];
console.log( A.quickSort() );