【问题标题】:JavaScript Quicksort recursiveJavaScript 快速排序递归
【发布时间】:2016-12-05 15:16:05
【问题描述】:

我正在尝试在 JavaScript 中为 int 数组实现快速排序算法。 我的代码有问题。前几个整数得到了很好的排序,但是在 sortet 数组的末尾总是有一个整数被放置了很多次,尽管它在数组中只有一次应该被排序。希望有人会发现我的错。 谢谢。

function quicksort(array) {
    var randomPlace = Math.round(Math.random() * array.length);
    var pivotelement = array[randomPlace];
    left = new Array;
    right = new Array;
    for (var i = 0; i < array.length; i++) {
        if (array[i] < pivot) {
            left[left.length] = array[i];
        } else {
            right[right.length] = array[i];
        }
    }
    if ((left.length == 0 || left.length == 1) && (right.length == 0 || right.length == 1)) {
        return left.concat(right);
    } else if (left.length == 0 || left.length == 1) {
        return (left.concat((quicksort(right))));
    } else if (right.length == 0 || right.length == 1) {
        return ((quicksort(left)).concat(right));
    } else {
        return (quicksort(left)).concat((quicksort(right)));
    }
}

【问题讨论】:

标签: javascript quicksort


【解决方案1】:

除了一些命名混乱,如pivotelement vs pivotMath.round vs Math.floor,您需要解决例如[1, 1, 1] 总是返回left = []right = [1, 1, 1] 的问题,即呼叫quicksort([1, 1, 1]) 无限。

为了克服这个问题,你需要检查空的leftright 每个元素,如果它等于随机枢轴。然后返回right,不再调用quicksort

function quicksort(array) {
    var randomPlace = Math.floor(Math.random() * array.length),
        pivot = array[randomPlace],
        left = [],
        right = [],
        i;

    for (i = 0; i < array.length; i++) {
        (array[i] < pivot ? left : right).push(array[i]);
    }
    console.log(pivot, JSON.stringify(array), JSON.stringify(left), JSON.stringify(right));

    // prevent looping forever
    if (!left.length && right.every(function (v) { return v === pivot; })) {
        return right;
    }

    if (left.length <= 1 && right.length <= 1) {
        return left.concat(right);
    }
    if (left.length <= 1) {
        return left.concat(quicksort(right));
    }
    if (right.length <= 1) {
        return quicksort(left).concat(right);
    }
    return quicksort(left).concat(quicksort(right));
}

console.log(quicksort([2, 7, 4, 8, 3, 11, 49, 20, 10, 1, 1, 1]));
.as-console-wrapper { max-height: 100% !important; top: 0; }

另一种解决方案是将数组分成三个数组,一个用于较小的值,一个用于相等的值,一个用于较大的值。然后只对更小和更大的数组进行排序。

function quicksort(array) {
    var randomPlace = Math.floor(Math.random() * array.length),
        pivotValue = array[randomPlace],
        left = [],
        pivot = [],
        right = [],
        i;

    for (i = 0; i < array.length; i++) {
        if (array[i] === pivotValue) {
            pivot.push(array[i]);
            continue;
        }
        (array[i] < pivotValue ? left : right).push(array[i]);
    }

    console.log(pivotValue, JSON.stringify(array), JSON.stringify(left), JSON.stringify(pivot), JSON.stringify(right));

    if (left.length <= 1 && right.length <= 1) {
        return left.concat(pivot, right);
    }
    if (left.length <= 1) {
        return left.concat(pivot, quicksort(right));
    }
    if (right.length <= 1) {
        return quicksort(left).concat(pivot, right);
    }
    return quicksort(left).concat(pivot, quicksort(right));
}

console.log(quicksort([2, 7, 4, 8, 3, 11, 49, 20, 10, 1, 1, 1]));
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

    【解决方案2】:

    这是一个用 JS 编写的快速排序的简短版本,与 Intro To Algorithms 中看到的完全一样,希望对您有所帮助!

    var partition = function (arr, low, high) {
        var x = arr[high]
        var i = low - 1
        for (var j = low; j <= high - 1; j++) {
            if (arr[j] <= x) {
                i++
                var temp = arr[i]
                arr[i] = arr[j]
                arr[j] = temp
            }
        }
        var temp = arr[i + 1]
        arr[i + 1] = arr[high]
        arr[high] = temp
        return i + 1 
    }
    
    var quickSort = function (arr, low, high) {
        if (low < high) {
            index = partition(arr,low,high)
            if (low < index-1) quickSort(arr,low,index-1)
            if (index+1 < high) quickSort(arr,index+1,high)
        }
    }
    
    var list2 = [1000,13,12,1001,82,1,2,4,3,0]
    
    console.log(quickSort(list2,0,list2.length))
    

    也在我的GitHub

    【讨论】:

      【解决方案3】:

      我认为您错误地识别了randomPlace。它有时会返回undefined,因为您使用的是Math.round()

      试试这个:

      var randomPlace = Math.floor(Math.random() * array.length);
      

      另外,在初始化leftright时使用以下代码:

      var left = new Array();
      var right = new Array();
      

      另外,您需要将array[i] &lt; pivot 中的pivot 更改为pivotElement

      你可以看到我完整的小提琴here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-14
        • 2013-10-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-15
        • 2020-04-18
        相关资源
        最近更新 更多