C# 什么';我的合并排序代码有什么问题?
我正在学习编码,我想我应该试着写一个合并排序算法(这是我们在分析课程中听到的,但不是家庭作业)。我是根据培训师向我们展示的伪代码工作的,但我无法确定问题所在。有没有可能有人能给我指出正确的方向 编辑:算法只返回列表中的第一个值C# 什么';我的合并排序代码有什么问题?,c#,algorithm,mergesort,C#,Algorithm,Mergesort,我正在学习编码,我想我应该试着写一个合并排序算法(这是我们在分析课程中听到的,但不是家庭作业)。我是根据培训师向我们展示的伪代码工作的,但我无法确定问题所在。有没有可能有人能给我指出正确的方向 编辑:算法只返回列表中的第一个值 static List<int> mergeSort(List<int> mj) { List<int>m = mj; if(m.Count <= 1) return m; List<
static List<int> mergeSort(List<int> mj)
{
List<int>m = mj;
if(m.Count <= 1)
return m;
List<int> merge = new List<int>();
List<int> left = new List<int>();
List<int> right = new List<int>();
int middle = m.Count/2;
for (int i = 0; i < middle; i++)
left.Add(m[i]);
for (int j = middle; j >= m.Count; j++)
right.Add(m[j]);
left = mergeSort(left);
right = mergeSort(right);
merge.AddRange(left);
merge.AddRange(right);
for (int k = 0; k < merge.Count; k++)
{
Console.Write(merge[k] + ",");
}
return merge;
}
静态列表合并排序(列表mj)
{
Listm=mj;
如果(m.Count=m.Count;j++)
对。添加(m[j]);
左=合并排序(左);
右=合并排序(右);
merge.AddRange(左);
merge.AddRange(右);
for(int k=0;k
此行:
for (int j = middle; j >= m.Count; j++)
right.Add(m[j]);
应改为:
for (int j = middle; j < m.Count; j++)
right.Add(m[j]);
for(int j=middle;j
此行:
for (int j = middle; j >= m.Count; j++)
right.Add(m[j]);
应改为:
for (int j = middle; j < m.Count; j++)
right.Add(m[j]);
for(int j=middle;j
简单的合并排序步骤
merge.AddRange(left);
merge.AddRange(right);
相反,您需要做的是迭代两个子列表(通过归纳,这两个子列表应该在递归调用中分别排序),并按顺序将元素添加到合并列表中
我们首先比较第0个元素:left[0]
和right[0]
。两者中较小的一个被添加到合并
列表中,其子列表的计数器递增。假设<代码>左[ 0 ] <右[ 0 ] < /代码>:我们将<代码>左[ 0 ] < /代码>添加到<代码>合并< /代码>,在下一次迭代中,我们需要考虑<代码>左[ 1 ] < /代码>反对<代码>右[ 0 ] < /代码>。如果<代码>左[ 1 ] < /代码>再次变小,则将其添加到<代码>合并< /代码>中,在下一次迭代中,考虑<代码>左[ 2 ] < /代码>反对<代码>右[ 0 ] < /代码>。如果right[0]
现在是两者中的较小者,我们将其添加到merge
中,并在下一次迭代中,将left[2]
与right[1]
进行比较。等等
这种情况一直持续到其中一个子列表耗尽为止。发生这种情况时,我们只需将剩余子列表中的所有元素添加到merge
int leftIndex = 0;
int rightIndex = 0;
while (leftIndex < left.Count && rightIndex < right.Count)
if (left[leftIndex] < right[rightIndex])
merge.Add(left[leftIndex++]);
else
merge.Add(right[rightIndex++]);
while (leftIndex < left.Count)
merge.Add(left[leftIndex++]);
while (rightIndex < right.Count)
merge.Add(right[rightIndex++]);
代码的问题(除了Mike Cowan提到的bug)是没有执行任何实际的排序。您首先递归地将列表一分为二(这是正确的),但随后您只是将它们按原始顺序重新连接在一起,因此没有得到任何结果:
merge.AddRange(left);
merge.AddRange(right);
相反,您需要做的是迭代两个子列表(通过归纳,这两个子列表应该在递归调用中分别排序),并按顺序将元素添加到合并列表中
我们首先比较第0个元素:left[0]
和right[0]
。两者中较小的一个被添加到合并
列表中,其子列表的计数器递增。假设<代码>左[ 0 ] <右[ 0 ] < /代码>:我们将<代码>左[ 0 ] < /代码>添加到<代码>合并< /代码>,在下一次迭代中,我们需要考虑<代码>左[ 1 ] < /代码>反对<代码>右[ 0 ] < /代码>。如果<代码>左[ 1 ] < /代码>再次变小,则将其添加到<代码>合并< /代码>中,在下一次迭代中,考虑<代码>左[ 2 ] < /代码>反对<代码>右[ 0 ] < /代码>。如果right[0]
现在是两者中的较小者,我们将其添加到merge
中,并在下一次迭代中,将left[2]
与right[1]
进行比较。等等
这种情况一直持续到其中一个子列表耗尽为止。发生这种情况时,我们只需将剩余子列表中的所有元素添加到merge
int leftIndex = 0;
int rightIndex = 0;
while (leftIndex < left.Count && rightIndex < right.Count)
if (left[leftIndex] < right[rightIndex])
merge.Add(left[leftIndex++]);
else
merge.Add(right[rightIndex++]);
while (leftIndex < left.Count)
merge.Add(left[leftIndex++]);
while (rightIndex < right.Count)
merge.Add(right[rightIndex++]);
首先,电话线
for (int j = middle; j >= m.Count; j++)
应该是
for (int j = middle; j < m.Count; j++)
应该是
mergeLeftRight(left, right)
其中mergeLeftRight是您定义的第二个函数,它执行实际排序。阅读维基百科关于合并排序的文章:首先,行
for (int j = middle; j >= m.Count; j++)
应该是
for (int j = middle; j < m.Count; j++)
应该是
mergeLeftRight(left, right)
其中mergeLeftRight是您定义的第二个函数,它执行实际排序。阅读维基百科关于合并排序的文章:那么,问题出在哪里?你没有描述它。你被困在哪里了?仅供参考,你不必在头衔后面加上“C”。这就是标签的作用。谢谢,对不起。它只返回列表中的第一个值。看起来你从来没有对int值进行过任何比较。还有其他问题,但在第二个for循环中,它应该是“j