【发布时间】:2017-04-10 04:29:02
【问题描述】:
我一直在对排序算法进行小修改,并遇到了合并排序。我已经编写了我的代码,并且在最后一小时一直在修改它,以确定它为什么仍然无法工作。我得到标准的 StackOverFlow 异常。谁能告诉我算法有什么问题?提前致谢。到目前为止,我设法写了以下内容:
public Int32[] MergeSort(Int32[] array)
{
int counter = 0;
if (array.Length == 0) { return array; }
int mid = array.Length / 2;
Int32[] leftHalf = new Int32[mid+1];
Int32[] rightHalf = new Int32[mid+1];
for (int i = 0; i < mid; i++) {
leftHalf[i] = array[i];
}
for (int j = mid; j < array.Length; j++) {
rightHalf[counter] = array[j];
counter++;
}
counter = 0;
MergeSort(leftHalf);
MergeSort(rightHalf);
return SortAndMerge(leftHalf,rightHalf);
}
public Int32[] SortAndMerge(Int32[] left, Int32[] right) {
Int32[] myResult = new Int32[left.Length+right.Length];
while (left.Length > 0 || right.Length > 0) {
if (left.Length > 0 && right.Length > 0)
{
if (left[0] <= right[0])
{
myResult[myResult.Length] = left[0];
int toRemoveIndex = Array.IndexOf(left, left[0]);
left = left.Where((x, y) => y != toRemoveIndex).ToArray();
}
else
{
myResult[myResult.Length] = right[0];
int toRemoveIndex = Array.IndexOf(right, right[0]);
right = right.Where((z, g) => g != toRemoveIndex).ToArray();
}
}
else if (left.Length > 0)
{
myResult[myResult.Length] = left[0];
int toRemoveIndex = Array.IndexOf(left, left[0]);
left = left.Where((x, y) => y != toRemoveIndex).ToArray();
}
else if (right.Length > 0) {
myResult[myResult.Length] = right[0];
int toRemoveIndex = Array.IndexOf(right, right[0]);
right = right.Where((x, y) => y != toRemoveIndex).ToArray();
}
}
return myResult;
}
【问题讨论】:
-
你能解释一下
counter在MergeSort函数中做了什么吗?...我的意思是我知道它在做什么,但是为什么不使用rightHalf[j - mid]而不是rightHalf[counter].. .可能会更清楚? -
很抱歉问Rustam,但是使用了这么多嵌套的if,真的需要吗?在寻找为什么会出现 SO 错误之前,我们是否应该考虑摆脱这些嵌套的 if,作为我修改算法的一部分,我将看看算法是否确实需要这样的丑陋。
-
调试器会给你一个堆栈跟踪,你可以逐行浏览代码。这会给你很多关于正在发生的事情的信息,尤其是关于永恒循环的信息。
-
在这些上下文中的堆栈溢出通常意味着“无限递归”。检查您的边界条件。
-
@DomFarolino 为了追加到 rightHalf 我使用计数器作为索引 rightHalf[0]、rightHalf[1] 等。[j-mid] 不会给你一个从 0+ 开始的自然序列+;
标签: c# algorithm sorting mergesort