繁体   English   中英

我的合并排序功能在 Java 中有效,但在 JavaScript 中无效,我错过了什么?

[英]My merge sort function works in Java but not in JavaScript, what am I missing?

我已经在 J​​ava 中实现了合并排序,它似乎工作正常。 我试图将此代码转移到 JavaScript 以创建合并排序排序算法的可视化表示,但我无法让相同的代码工作。

这是我的 Java 实现的代码:

'''

public class MergeSort {

    public void merge(int[] arr, int[] tmpArr, int lo, int mid, int hi) {

        for (int k = lo; k <= hi; k++) {  // first we copy over the array to our tmp array
            tmpArr[k] = arr[k];
        }

        int left = lo;         // keeps index of left side of tmp array
        int right = mid + 1;    // keeps index of right side of tmp array

        for (int l = lo; l <= hi; l++) {  // l keeps the index of the sorted array
            if (left > mid) {               // will merge remaining values in right side of array
                arr[l] = tmpArr[right];
                right++;
            } else if (right > hi) {         // will merge remaining values in left side of array
                arr[l] = tmpArr[left];
                left++;
            } else if (tmpArr[left] < tmpArr[right]) {  // checks if value in left array is less than value in right array
                arr[l] = tmpArr[left];
                left++;
            } else {
                arr[l] = tmpArr[right];
                right++;
            }
        }
    }

    public void sort(int[] arr) {
        int[] tmpArr = new int[arr.length];
        sort(arr, tmpArr, 0, arr.length - 1);
    }

    public void sort(int[] arr, int[] tmpArr, int lo, int hi) {
        if (lo >= hi) {
            return;
        }

        int mid = lo + ((hi - lo) / 2);
        sort(arr, tmpArr, lo, mid);
        sort(arr, tmpArr, mid + 1, hi);
        merge(arr, tmpArr, lo, mid, hi);
    }
}

'''

这是我的 JavaScript 实现:

'''

function merge(arr, tmpArr, lo, mid, hi) {
    tmpArr = arr.slice(lo, hi + 1); // copy array over to tmp array

    left = lo; // keeps index of left side of tmp array
    right = mid + 1; // keeps index of right side of tmp array

    for (index = lo; index <= hi; index++) { // index keeps the index of the sorted array
        if (left > mid) { // will merge remaining values in right side of array
            arr[index] = tmpArr[right];
            right++;
        } else if (right > hi) { // will merge remaining values in left side of array
            arr[index] = tmpArr[left];
            left++;
        } else if (tmpArr[left] < tmpArr[right]) { // checks if value in left array is less than value in right array
            arr[index] = tmpArr[left];
            left++;
        } else if (tmpArr[right] < tmpArr[left]) {
            arr[index] = tmpArr[right];
            right++;
        }
    }
}

function sort(arr, tmpArr, lo, hi) {
    if (lo >= hi) { // gets rid of edge case where array has 1 element
        return;
    }

    mid = Math.floor(lo + ((hi - lo) / 2));
    sort(arr, tmpArr, lo, mid);
    sort(arr, tmpArr, (mid + 1), hi);
    merge(arr, tmpArr, lo, mid, hi);
}

function mergeSort(arr) {
    tmpArr = [];
    sort(arr, tmpArr, 0, arr.length - 1);
}

'''

我花了几个小时调整这段代码并将打印语句插入到我的代码中,但我似乎不明白为什么它可以在 Java 中工作而不是在 JavaScript 中工作。 我比 JavaScript 更精通 Java,所以我想我可能遗漏了一些东西。 任何帮助将不胜感激,在此先感谢您。

我不能说这一切都错了,但这马上就跳出来了:

 tmpArr = arr.slice(lo, hi + 1); // copy array over to tmp array

这并不像它所说的那样做。 与 Java 一样,它重新分配参数tmpArr以引用新数组。 这意味着传入的那个永远不会被修改。

如果你想用你列出的内容替换tmpArr的内容,你需要按照你在 Java 中的方式来做(或者使用最终做同样事情的内置方法,比如tmpArr.length = 0; tmpArr.push(...arr.slice(lo, hi + 1)); )。

  1. 直接在tmpArray中的索引处设置值。 使用slice将不允许使用与原始数组中相同的索引进行访问。
for(let i = lo; i <= hi; i++) tmpArr[i] = arr[i];
  1. 不要在函数内部使用全局变量。 letconst来声明它们。 这会导致您的sort函数失败,因为mid由递归调用更新(因为它是隐式全局的),因此使用错误的参数调用merge
function sort(arr, tmpArr, lo, hi) {
    if (lo >= hi) {
        return;
    }

    let mid = lo + Math.floor((hi - lo) / 2);
    sort(arr, tmpArr, lo, mid);
    sort(arr, tmpArr, mid + 1, hi);
    merge(arr, tmpArr, lo, mid, hi);
}

 function merge(arr, tmpArr, lo, mid, hi) { for (let k = lo; k <= hi; k++) { tmpArr[k] = arr[k]; } let left = lo; // keeps index of left side of tmp array let right = mid + 1; // keeps index of right side of tmp array for (let l = lo; l <= hi; l++) { // l keeps the index of the sorted array if (left > mid) { // will merge remaining values in right side of array arr[l] = tmpArr[right]; right++; } else if (right > hi) { // will merge remaining values in left side of array arr[l] = tmpArr[left]; left++; } else if (tmpArr[left] < tmpArr[right]) { // checks if value in left array is less than value in right array arr[l] = tmpArr[left]; left++; } else { arr[l] = tmpArr[right]; right++; } } } function mergeSort(arr) { tmpArr = []; sort(arr, tmpArr, 0, arr.length - 1); } function sort(arr, tmpArr, lo, hi) { if (lo >= hi) { return; } let mid = lo + Math.floor((hi - lo) / 2); sort(arr, tmpArr, lo, mid); sort(arr, tmpArr, mid + 1, hi); merge(arr, tmpArr, lo, mid, hi); } let arr = [3, -1, 5, 6, 8, 2, 2, 1]; mergeSort(arr); console.log(arr);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM