简体   繁体   English

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

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

I have implemented merge sort in Java and it seems to be working correctly.我已经在 J​​ava 中实现了合并排序,它似乎工作正常。 I have tried to transfer this code over to JavaScript in order to create a visual representation of the merge sort sorting algorithm and I cannot get this same code to work.我试图将此代码转移到 JavaScript 以创建合并排序排序算法的可视化表示,但我无法让相同的代码工作。

Here is the code for my Java implementation:这是我的 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);
    }
}

''' '''

Here is my JavaScript implementation:这是我的 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);
}

''' '''

I have spent hours tweaking this code and inserting print statements into my code but I can't seem to see why it would work in Java and not JavaScript.我花了几个小时调整这段代码并将打印语句插入到我的代码中,但我似乎不明白为什么它可以在 Java 中工作而不是在 JavaScript 中工作。 I am much more proficient in Java than JavaScript so I assume maybe I am missing something.我比 JavaScript 更精通 Java,所以我想我可能遗漏了一些东西。 Any help would be greatly appreciated, thank you in advance.任何帮助将不胜感激,在此先感谢您。

I can't say it's everything that's wrong, but this jumped out right away:我不能说这一切都错了,但这马上就跳出来了:

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

This doesn't do what it says it does.这并不像它所说的那样做。 Just as with Java, it reassigns the parameter tmpArr to refer to a new array.与 Java 一样,它重新分配参数tmpArr以引用新数组。 That means the one that is passed in is never modified.这意味着传入的那个永远不会被修改。

If you want to replace tmpArr 's contents with the contents you've listed, you need to do it the way you did it in Java (or with built-in methods that end up doing the same thing, such as tmpArr.length = 0; tmpArr.push(...arr.slice(lo, hi + 1)); ).如果你想用你列出的内容替换tmpArr的内容,你需要按照你在 Java 中的方式来做(或者使用最终做同样事情的内置方法,比如tmpArr.length = 0; tmpArr.push(...arr.slice(lo, hi + 1)); )。

  1. Directly set the value at the indexes in tmpArray .直接在tmpArray中的索引处设置值。 Using slice will not allow accessing with the same indexes as in the original array.使用slice将不允许使用与原始数组中相同的索引进行访问。
for(let i = lo; i <= hi; i++) tmpArr[i] = arr[i];
  1. Don't use global variables inside the functions.不要在函数内部使用全局变量。 Declare them with let or const instead.letconst来声明它们。 This causes your sort function to fail because mid is updated by the recursive call (since it is implicitly global), so merge gets called with the wrong arguments.这会导致您的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