簡體   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