【问题标题】:How to fix this implementaion of the Merge Sort in c#如何在 c# 中修复此合并排序的实现
【发布时间】:2019-07-13 19:18:37
【问题描述】:

我已阅读 CLRS 并尝试实现递归合并排序算法。看不到错误是什么,但每次我运行它都会给我一个“索引超出范围错误”

我已经尝试了 5 个小时了

static public void MergeSort(int[] input, int IndexStanga, int IndexDreapta)
{
    if (IndexStanga < IndexDreapta)
    {
        int IndexMijloc = (IndexDreapta + IndexStanga) / 2;
        MergeSort(input, IndexStanga, IndexMijloc);
        MergeSort(input, IndexMijloc + 1, IndexDreapta);

        Merge(input, IndexStanga, IndexDreapta, IndexMijloc);
    }
}

static public void Merge(int[] input, int stanga, int dreapta, int mijloc)
{
    int lungDR = 0;
    int lunST = 0;
    lungDR = dreapta - mijloc;
    lunST = mijloc - stanga + 1;
    int[] valDreapta = new int[lungDR + 1];
    int[] valStanga = new int[lunST + 1];

    valDreapta[valDreapta.Length - 1] = int.MaxValue;
    valStanga[valStanga.Length - 1] = int.MaxValue;

    int i = 0;
    int j = 0;

    for (i = stanga; i <= mijloc; i++) valStanga[i] = input[i];

    for (i = 0; i < lungDR; i++) { valDreapta[i] = input[i + mijloc + 1]; }

    i = 0;
    j = 0;

    for (int k = 0; k < input.Length; k++)
    {
        if (valStanga[i] <= valDreapta[j]) //error out of bounds 
        {
            input[k] = valStanga[i];
            i++;
        }
        else
        {
            input[k] = valDreapta[j];
            j++;
        }
    }
}

【问题讨论】:

  • 作为对 Stack Overflow 上所有非罗马尼亚开发人员的服务,您能否将参数等重命名为英文以使其更易于理解,从问题中删除一层抽象?跨度>
  • 知道错误的行号也很好......虽然我怀疑它是使用ij索引但未在条件语句中使用的地方for 循环。
  • 使用调试器。它会准确告诉您错误发生的位置,您可以检查所有值是否正确。
  • 对不起,我匆忙发布了这个问题,老实说,我没想到会有任何答案......无论如何,伙计们!
  • 错误位于“ for (int k = 0; k

标签: c# algorithm mergesort


【解决方案1】:

在下面的 cmets 中指出的修复。首次修复将数据从输入移动到 valStanga。第二次修复合并回输入的范围。合并的参数是一个不寻常的顺序,第一,最后,中间。通常顺序是第一、中间、最后。

注释:如果要排序的数组包含等于最大整数的元素,程序将出现问题。一次性分配工作数组会更有效,而不是在每次调用合并时分配新的子数组。可以通过每一级递归改变合并方向来避免复制操作。

    int i = 0;
    int j = 0;

    for (i = 0; i < lungDR; i++) { valDreapta[i] = input[i + mijloc + 1]; }
    for (i = 0; i < lunST; i++) { valStanga[i] = input[i + stanga]; }      // fix

    i = 0;
    j = 0;

    for (int k = stanga; k <= dreapta; k++)                                // fix
    {
        if (valStanga[i] <= valDreapta[j])

【讨论】:

  • @StefanAdrian - merge sort 的 wiki 文章显示了一种经过一定程度优化的自上而下的合并排序,它只执行一次分配和一次复制,然后为每个递归级别交替合并方向。一对相互递归的函数将消除一次复制的需要。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-11
  • 1970-01-01
  • 2020-10-07
相关资源
最近更新 更多