【问题标题】:implement quicksort recursive function on prototype array在原型数组上实现快速排序递归函数
【发布时间】:2017-08-23 14:25:11
【问题描述】:
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 上在线浏览了一些,但它与计算运行函数的成本不同。

【问题讨论】:

    标签: javascript arrays algorithm sorting ecmascript-6


    【解决方案1】:

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

    • 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() );

    【讨论】:

    • 请问这行代码可以吗?我不明白 [0, 0] 是指。 self.splice.apply(self, [0, 0].concat(right.quickSort()));
    • [ 0, 0 ].concat( right.quickSort() ) 在已排序的右分区的开头添加 0, 00, 0splice 的前两个参数,表示在位置 0 添加项目并删除 0 个项目。 Splice 不期望数组作为它的 items 参数;通过使用apply,您可以直接将您的项目数组传递给splice,而不必遍历它们并一一添加。
    • 嗨,我刚刚做了一个测试,如果我使用 [1,10,6,5,4,3,7,9],只要数组在至少 2 秒内形成,它就会被窃听。
    • 我真的听不懂你,但我用那个输入测试了它,它仍然有效。
    • 当我输入 1,10,6,5,4,3,7,9 结果是 1,3,4,5,7,6,9,10:7 和6 未排序。
    【解决方案2】:
    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() );
    

    【讨论】:

      猜你喜欢
      • 2019-11-16
      • 1970-01-01
      • 1970-01-01
      • 2020-08-14
      • 1970-01-01
      • 2013-10-08
      • 1970-01-01
      • 1970-01-01
      • 2011-12-18
      相关资源
      最近更新 更多