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
简单的合并排序步骤

  • 如果(mj.length==1)返回mj
  • 拆分为左列表和右列表并递归

  • 当左列表和右列表返回时,合并它们简单的合并排序步骤

  • 如果(mj.length==1)返回mj
  • 拆分为左列表和右列表并递归

  • 当左列表和右列表返回时,将它们合并。代码的问题(除了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++]);
    

    代码的问题(除了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=m.Count”。那么,问题是什么?你没有描述它。你被困在哪里了?仅供参考,你不必在头衔后面加上“C”。这就是标签的作用。谢谢,对不起。它只返回列表中的第一个值。看起来你从来没有对int值进行过任何比较。还有其他问题,但在第二个for循环中,它应该是“j=m.Count”。当然,代码还有其他问题(即,它没有排序任何东西)但它可能仍在进行中。谢谢=)现在它返回了,但还远没有排序。@JeffMercado这是一个正在进行的工作,但这个提示是一个很好的提示=)代码当然还有其他问题(即,它没有排序任何东西)但它可能仍在进行中。谢谢=)现在它返回了,但距离排序还有一段距离。@JeffMercado它是一项非常重要的工作