在JavaScript中构建mergesort时的无限循环

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在JavaScript中构建mergesort时的无限循环相关的知识,希望对你有一定的参考价值。

我正在尝试构建一个猴子修补版本的mergeSort,但我每次都遇到错误。我已经运行了几次调试器,看起来一切都正常排序,直到最后一步我跳转到loader.js文件中的一行。

任何人都可以帮我看一下吗?提前致谢!


Array.prototype.mergeSort = function(callback) {
    if (this.length <= 1) return this;

    if (!callback) {
        callback = function(x, y) {
            if (x > y) return -1;
            else if (x < y) return 1;
            else return 0;
        };
    }

    const mid = Math.floor(this.length / 2);
    const sortedLeft = this.slice(0, mid).mergeSort(callback);
    const sortedRight = this.slice(mid).mergeSort(callback);

    return sortedLeft.merge(sortedRight, callback);
};

Array.prototype.merge = function(arr, callback) {
    let merged = [];

    while (this.length > 0 || arr.length > 0) {
        if (callback(this[0], arr[0]) < 0) {
            merged.push(arr.shift());
            break;
        } else if (callback(this[0], arr[0]) >= 0) {
            merged.push(this.shift());
            break;
        }
    }

    merged = merged.concat(this);
    merged = merged.concat(arr);

    return merged;
};

答案

当任一列表为空时,合并循环应该停止:而不是while (this.length > 0 || arr.length > 0)你应该写:

while (this.length > 0 && arr.length > 0)

此外,你不应该在每个商店进入break数组后从循环中merge,并且两次比较元素是多余的。

这是一个更正版本:

Array.prototype.merge = function(arr, callback) {
    let merged = [];

    while (this.length > 0 && arr.length > 0) {
        if (callback(this[0], arr[0]) < 0) {
            merged.push(arr.shift());
        } else {
            merged.push(this.shift());
        }
    }
    merged = merged.concat(this);
    return merged.concat(arr);
};

但请注意,您的merge方法按降序对数组进行排序,默认的callback函数也按降序对元素进行比较,导致数组按重合顺序递增排序。您可能希望简化此操作并接受null中的merge回调函数。

这是一个更通用的版本:

Array.prototype.mergeSort = function(callback) {
    if (this.length <= 1)
        return this;

    const mid = this.length >> 1;
    const sortedLeft = this.slice(0, mid).mergeSort(callback);
    const sortedRight = this.slice(mid).mergeSort(callback);

    return sortedLeft.merge(sortedRight, callback);
};

Array.prototype.merge = function(arr, callback) {
    let merged = [];

    if (callback) {
        while (this.length > 0 && arr.length > 0) {
            if (callback(this[0], arr[0]) <= 0) {
                merged.push(this.shift());
            } else {
                merged.push(arr.shift());
            }
        }
    } else {
        while (this.length > 0 && arr.length > 0) {
            if (this[0] <= arr[0]) {
                merged.push(this.shift());
            } else {
                merged.push(arr.shift());
            }
        }
    }
    return merged.concat(this).concat(arr);
};

以上是关于在JavaScript中构建mergesort时的无限循环的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 MergeSort 中使用 InsertionSort 而不是 Merge 平均更快?

显示用户在文本框中键入指定字符时的建议

Javascript 速记 - '||' 是啥意思运算符在作业中使用时的意思? [复制]

在 javascript 中实例化 QWebChannel 对象时的警告

构建时的 SqlServer 类型错误

在 xcode 6 中构建旧应用程序时的布局问题