问题描述
大家! 我正在尝试在C#中实现合并排序算法。我的代码中有一个StackOverflow异常。 我正在尝试找出问题所在,但无法解决。
using System;
class MainClass {
static void merge(int[] arr,int leftIndex,int endLeftIndex,int endRightIndex){
// leftArr [leftIndex ... endLeftIndex]
// rightArr [endLeftIndex + 1 ... endRightIndex]
int leftArrLength = endLeftIndex - leftIndex + 1;
int rightArrLength = endRightIndex - endLeftIndex;
int[] leftArr = new int[leftArrLength],rightArr = new int[rightArrLength];
// Copying the data from the parent Array to the leftArr & rightArr
for(int i = 0; i < leftArrLength; i++)
leftArr[i] = arr[leftIndex + i];
for(int j = 0; j < rightArrLength; j++)
rightArr[j] = arr[endLeftIndex + j + 1];
// the start index of the array that will be merged
int mergedArrIndex = leftIndex;
// set two start pointers for both left and right arrays
int leftIndexMerge = 0,rightIndexMerge = 0;
// the merging operation
while(leftIndexMerge < leftArrLength && rightIndexMerge < rightArrLength){
if(leftArr[leftIndexMerge] < rightArr[rightIndexMerge])
arr[mergedArrIndex++] = leftArr[leftIndexMerge++];
else
arr[mergedArrIndex++] = rightArr[rightIndexMerge++];
}
// copying the rest elements
while(leftIndexMerge < leftArrLength)
arr[mergedArrIndex++] = leftArr[leftIndexMerge++];
while(rightIndexMerge < rightArrLength)
arr[mergedArrIndex++] = rightArr[rightIndexMerge++];
}
static void mergeSort(int[] arr,int endRightIndex){
if(leftIndex < endRightIndex){
// leftArr [leftIndex ... m]
// rightArr [m + 1 ... endRightIndex]
int m = leftIndex + (endRightIndex - 1) / 2;
mergeSort(arr,leftIndex,m);
mergeSort(arr,m + 1,endRightIndex);
merge(arr,m,endRightIndex);
}
}
public static void Main (string[] args) {
int[] arr = {1,2,5,10,1,3,4,4};
mergeSort(arr,arr.Length);
foreach(int i in arr) Console.WriteLine(i);
}
}
查看repl.it中的代码:https://repl.it/@MohamedMarzouk/MergeSortImplementationInCSharp
解决方法
您遇到2个问题
导致堆栈溢出的第一个
// int m = leftIndex + (endRightIndex - 1) / 2;
// should be
int m = leftIndex + (endRightIndex - leftIndex) / 2;
查看源代码,您只是将l
误认为1
以及以下会给您索引超出范围错误的错误
// mergeSort(arr,arr.Length);
// should be
mergeSort(arr,arr.Length-1);
没有任何借口:)
,您的代码中有2个问题:
-
中间索引计算不正确:
int m = leftIndex + (endRightIndex - 1) / 2;
应该int m = leftIndex + (endRightIndex - leftIndex) / 2;
从 -
参数不正确:
mergeSort(arr,arr.Length)
应该mergeSort(arr,arr.Length - 1);
Main
进行初始呼叫传递的这表明包括开始和结束边界索引的约定容易出错。如果排除endRightIndex
和endLeftIndex
,则不再需要+1
/ -1
调整。我希望教程会停止教授这种废话。
这是简化版:
using System;
class MainClass {
static void merge(int[] arr,int leftIndex,int rightIndex,int endIndex) {
// leftArr [leftIndex ... endLeftIndex)
// rightArr [endLeftIndex ... endIndex)
int leftArrLength = rightIndex - leftIndex;
int rightArrLength = endIndex - RightIndex;
int[] leftArr = new int[leftArrLength];
int[] rightArr = new int[rightArrLength];
// Copying the data from the parent Array to the leftArr & rightArr
for (int i = 0; i < leftArrLength; i++)
leftArr[i] = arr[leftIndex + i];
for (int j = 0; j < rightArrLength; j++)
rightArr[j] = arr[rightIndex + j];
// the start index of the array that will be merged
int mergedArrIndex = leftIndex;
// set two start pointers for both left and right arrays
int leftIndexMerge = 0,rightIndexMerge = 0;
// the merging operation
while (leftIndexMerge < leftArrLength && rightIndexMerge < rightArrLength) {
if (leftArr[leftIndexMerge] <= rightArr[rightIndexMerge])
arr[mergedArrIndex++] = leftArr[leftIndexMerge++];
else
arr[mergedArrIndex++] = rightArr[rightIndexMerge++];
}
// copying the rest elements
while (leftIndexMerge < leftArrLength)
arr[mergedArrIndex++] = leftArr[leftIndexMerge++];
// This final loop is actually redundant: these elements are already in place
//while (rightIndexMerge < rightArrLength)
// arr[mergedArrIndex++] = rightArr[rightIndexMerge++];
}
static void mergeSort(int[] arr,int endIndex) {
if (endIndex - leftIndex >= 2) {
// leftArr [leftIndex ... m)
// rightArr [m ... endIndex)
int m = leftIndex + (endIndex - leftIndex) / 2;
mergeSort(arr,leftIndex,m);
mergeSort(arr,m,endIndex);
merge(arr,endIndex);
}
}
public static void Main(string[] args) {
int[] arr = { 1,2,5,10,1,3,4,4 };
mergeSort(arr,arr.Length);
foreach (int n in arr)
Console.WriteLine(n);
}
}