[英]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.我已经在 Java 中实现了合并排序,它似乎工作正常。 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));
)。
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];
let
or const
instead.let
或const
来声明它们。 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.