【问题标题】:MergeSort() implementation returning the initial unsorted arrayMergeSort() 实现返回初始未排序数组
【发布时间】:2018-08-29 17:56:15
【问题描述】:

每次我运行它都会返回一个未排序的数组。我已经放置了一些代码来告诉我事情在哪里发生和没有发生,但看起来一切正常,但它实际上不会对任何事情进行排序。

 public static int[] MergeSort(int[] array)
    {
        if(array.Length <= 1)
        {
            return array;
        }
        (int[], int[]) p = SplitArray(array);
        int[] left = MergeSort(p.Item1);
        int[] right = MergeSort(p.Item2);
        return Merge(left, right);


    }



    public static int[] Merge(int[] low, int[] high)
    {
        int[] middle = new int[(low.Length + high.Length + 1)];
        int count = 0;
        foreach (int item in low)
        {
            Console.WriteLine("low: " + item + ',');
        }
        foreach (int item in high)
        {
            Console.WriteLine("high: " + item + ',');
        }
        int low_index = 0;
        int high_index = 0;
        while (low_index < low.Length && high_index < high.Length)
        {
            if(low[low_index] < high[high_index])
            {
                middle.SetValue(low[low_index], count);
                low_index++;
                count++;
                Console.WriteLine("Low inserted.");
            }
            else
            {
                middle.SetValue(high[high_index], count);
                high_index++;
                count++;
                Console.WriteLine("High inserted.");
            }

        }
        if (low_index == low.Length)
        {
            high.CopyTo(middle, high_index);
        }
        else
        {
            low.CopyTo(middle, low_index);
        }

        return middle;
    }


    public static (int[], int[]) SplitArray(int[] k)
    {
        int MAXINDEX = k.Length - 1;
        int count = 0;
        int[] a = new int[(MAXINDEX / 2)];
        int[] b = new int[(MAXINDEX / 2)];

        for (int i = 0; i < (MAXINDEX / 2); i++)
        {
            a[i] = k[i];
        }
        for (int i = ((MAXINDEX / 2) + 1); i < MAXINDEX; i++)
        {
            b[count] = k[i];
            count++;

        }
        return (a, b);

    }

我不知道我哪里出错了。每次回到这里,我可能只是因为非常疲倦而忽略了一些事情。我基本上打印了一堆应该使用控制台发生的事情,这一切似乎都是正确的,我正在失去理智。

【问题讨论】:

  • 为什么不从一个小数组开始,然后使用调试器单步调试您的代码,以便您了解发生了什么?
  • 我一直在这样做。我忘了在我的帖子中剪掉 Console.WriteLine ,但我基本上是通过一堆随机生成的数组来运行它,这些数组看起来都像函数按照我想要的方式运行,但它一直给我初始数组.
  • @MasonHanna 您的 CopyTo 方法末尾的 Merge() 行看起来不对。您正在尝试复制已添加到 middle 数组中的数组。或者您开始​​将它们重新添加到 middle 数组的开头。使用两个普通的while 循环从其中一个数组中复制剩余的数字可能更容易。
  • @Progman 执行此操作后,我现在注意到我的拆分功能有些问题,其中一些项目在拆分过程中被丢弃......无论如何它正在打印。某些东西要么被丢弃,要么在不应该的时候变成了一个 0 数组。
  • 所以在大家的帮助下,我不仅确定了哪里出了问题,还弄清楚了为什么我的打印数组总是一样的。我重新打印了未排序的数组,而不是打印排序后的数组!我真的不知道如何感谢你们,但也许我会发布我所做的并在我下班后将其作为我的答案。非常感谢大家!

标签: c# mergesort


【解决方案1】:

好的,我认为主要的错误是 high.copyTo(...) 和 low.copyTo(...) 的函数索引错误

这里是完整的源代码(已测试):

public static int[] MergeSort(int[] array)
{
  if (array.Length <= 1)
  {
    return array;
  }

  Tuple<int[], int[]> p = SplitArray(array);

  int[] left = MergeSort(p.Item1);
  int[] right = MergeSort(p.Item2);

  return Merge(left, right);
}

public static int[] Merge(int[] low, int[] high)
{
  int[] middle = new int[low.Length + high.Length];
  int count = 0;
  foreach (int item in low)
  {
    Console.WriteLine("low: " + item + ',');
  }
  foreach (int item in high)
  {
    Console.WriteLine("high: " + item + ',');
  }
  int low_index = 0;
  int high_index = 0;
  while (low_index < low.Length && high_index < high.Length)
  {
    if (low[low_index] < high[high_index])
    {
      middle[count] = low[low_index];
      low_index++;
      count++;
      Console.WriteLine("Low inserted.");
    }
    else
    {
      middle[count] = high[high_index];
      high_index++;
      count++;
      Console.WriteLine("High inserted.");
    }

  }
  if (low_index == low.Length)
  {
    for (; count < middle.Length; count++)
    {
      middle[count] = high[high_index];
      high_index++;
    }

    // alternate: Array.Copy(high, high_index, middle, count, middle.Length - count);
  }
  else
  {
    for (; count < middle.Length; count++)
    {
      middle[count] = low[low_index];
      low_index++;
    }
    // alternate: Array.Copy(low, low_index, middle, count, middle.Length - count);
  }

  return middle;
}

public static Tuple<int[], int[]> SplitArray(int[] k)
{
  int half = k.Length / 2;
  int[] a = new int[half];
  int[] b = new int[k.Length - half];

  int k_index = 0;

  for (int i = 0; i < a.Length; i++)
  {
    a[i] = k[k_index];
    k_index++;
  }

  for (int i = 0; i < b.Length; i++)
  {
    b[i] = k[k_index];
    k_index++;
  }

  return new Tuple<int[], int[]>(a, b);
}

【讨论】:

    【解决方案2】:

    你去吧:代码充满了错误,数组的长度不匹配,你每次都覆盖你的中间数组。

    namespace MainClass
    {
        class Program
        {
            static void Main(string[] args)
            {
                int[] array = { 3, 5, 15, 22, 12, 15, 23 };
    
                int[] x = MergeSort(array);
    
                foreach (int i in x)
                {
                    Console.WriteLine(i);
                }
    
                Console.ReadKey();
            }
        public static int[] MergeSort(int[] array)
        {
            if (array.Length <= 1)
            {
                return array;
            }
            (int[], int[]) p = SplitArray(array);
            int[] left = MergeSort(p.Item1);
            int[] right = MergeSort(p.Item2);
            return Merge(left, right);
    
    
        }
    
    
    
        public static int[] Merge(int[] low, int[] high)
        {
            int[] middle = new int[(low.Length + high.Length)];
            int count = 0;
            foreach (int item in low)
            {
                Console.WriteLine("low: " + item + ',');
            }
            foreach (int item in high)
            {
                Console.WriteLine("high: " + item + ',');
            }
            int low_index = 0;
            int high_index = 0;
            while (low_index < low.Length && high_index < high.Length)
            {
                if (low[low_index] < high[high_index])
                {
                    middle.SetValue(low[low_index], count);
                    low_index++;
                    count++;
                    Console.WriteLine("Low inserted.");
                }
                else
                {
                    middle.SetValue(high[high_index], count);
                    high_index++;
                    count++;
                    Console.WriteLine("High inserted.");
                }
    
            }
            while (high_index < high.Length)
            {
                middle[low_index + high_index] = high[high_index++];
            }
            while (low_index < low.Length)
            {
                middle[low_index + high_index] = low[low_index++];
            }
    
            return middle;
        }
    
    
        public static (int[], int[]) SplitArray(int[] k)
        {
            int[] a = new int[((k.Length + 1) / 2)];
            int[] b = new int[(k.Length / 2)];
    
            for (int i = 0; i < a.Length; i++)
            {
                a[i] = k[i];
            }
            for (int i = 0; i < b.Length; i++)
            {
                b[i] = k[i + a.Length];
            }
            return (a, b);
    
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-20
      • 1970-01-01
      相关资源
      最近更新 更多