C# 中的合并排序实现 - StackOverflow 异常
Merge Sort Implementation in C# - StackOverflow Exception
大家好!
我正在尝试在 C# 中实现合并排序算法。我的代码有一个 Whosebug 异常。
我想弄清楚问题出在哪里,但我无法解决。
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 leftIndex, 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, leftIndex, m, endRightIndex);
}
}
public static void Main (string[] args) {
int[] arr = {1,2,5,10,1,2,3,4,4};
mergeSort(arr, 0, 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, 0, arr.Length);
// should be
mergeSort(arr, 0, arr.Length-1);
没有任何借口:)
您的代码中有 2 个问题:
中间索引计算不正确:int m = leftIndex + (endRightIndex - 1) / 2;
应该是
int m = leftIndex + (endRightIndex - leftIndex) / 2;
从 Main
初始调用传递的参数不正确:mergeSort(arr, 0, arr.Length)
应该是
mergeSort(arr, 0, arr.Length - 1);
这表明包含开始和结束边界索引的约定很容易出错。如果 endRightIndex
和 endLeftIndex
被排除,则不再需要 +1
/ -1
调整。我希望教程停止教授这个 non-sense.
这是一个简化版本:
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 leftIndex, 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, leftIndex, m, endIndex);
}
}
public static void Main(string[] args) {
int[] arr = { 1, 2, 5, 10, 1, 2, 3, 4, 4 };
mergeSort(arr, 0, arr.Length);
foreach (int n in arr)
Console.WriteLine(n);
}
}
大家好! 我正在尝试在 C# 中实现合并排序算法。我的代码有一个 Whosebug 异常。 我想弄清楚问题出在哪里,但我无法解决。
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 leftIndex, 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, leftIndex, m, endRightIndex);
}
}
public static void Main (string[] args) {
int[] arr = {1,2,5,10,1,2,3,4,4};
mergeSort(arr, 0, 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, 0, arr.Length);
// should be
mergeSort(arr, 0, arr.Length-1);
没有任何借口:)
您的代码中有 2 个问题:
中间索引计算不正确:
int m = leftIndex + (endRightIndex - 1) / 2;
应该是int m = leftIndex + (endRightIndex - leftIndex) / 2;
从
Main
初始调用传递的参数不正确:mergeSort(arr, 0, arr.Length)
应该是mergeSort(arr, 0, arr.Length - 1);
这表明包含开始和结束边界索引的约定很容易出错。如果 endRightIndex
和 endLeftIndex
被排除,则不再需要 +1
/ -1
调整。我希望教程停止教授这个 non-sense.
这是一个简化版本:
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 leftIndex, 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, leftIndex, m, endIndex);
}
}
public static void Main(string[] args) {
int[] arr = { 1, 2, 5, 10, 1, 2, 3, 4, 4 };
mergeSort(arr, 0, arr.Length);
foreach (int n in arr)
Console.WriteLine(n);
}
}