【问题标题】:How to sort first M elements in N length array?如何对 N 长度数组中的前 M 个元素进行排序?
【发布时间】:2012-11-27 02:08:16
【问题描述】:

我有一些关于在 C# 中对数组进行排序的任务。我一直在尝试我能想到的一切——没有运气。

任务是通过已知的排序算法(插入、选择、冒泡、快速)对整数数组进行排序。问题是,我必须ONLY 对最小的M 元素进行排序。

示例:我有一个包含 7 个元素 2 9 8 3 4 15 11 的数组,我需要对最小的 3 个元素进行排序,以便我的数组变为 2 3 4 9 8 15 11

请帮忙,我似乎无法在 SO 中找到任何东西,也无法通过 Google 找到任何东西。我不要求为我做所有的算法,我只需要其中一个来掌握这怎么可能。

E:谢谢你的想法。我已经查看了您的所有建议,并完成了这样的插入排序:

static int[] insertSort(int[] arr, out int swaps, out int checks) {
    int step = 0;
    swaps = 0;
    checks = 0;
    for (int i = 0; i < arr.Length; i++) {
        int min = arr[i], minind = i;
        for (int j = i + 1; j < arr.Length; j++) {
            checks++;
            if (arr[j] < min) {
                min = arr[j];
                minind = j;
            }
        }
        int temp = arr[minind];
        if (step < M) {
            for (int j = minind; j > i; j--) {
                swaps++;
                arr[j] = arr[j - 1];
            }
            arr[i] = temp;
            swaps++;
            step++;
        }
    }
    return arr;
}

交换和检查 - 我的应用程序的要求。

附:我多次看到 SO 不喜欢为某人做作业。这就是我没有要求提供代码的原因,我只是询问了有关如何实现这一点的想法。

再次感谢那些在这里帮助过我的人。

【问题讨论】:

  • 为什么这么难?您只是假装数组比实际短并对其进行排序。
  • @Earlz 再次阅读问题……
  • 我有 95% 的把握,你的老师让你只对前几项进行排序的全部原因是,你不能只使用可以在网上找到的现有解决方案。 (至少要对它们进行足够的修改以证明您对它们的工作原理有所了解。)
  • 效率有什么限制吗?一种天真的方法会很简单。
  • 如何将2 9 8 3 4 15 11 中的前三个元素排序为2 3 4 9 8 15 11

标签: c# arrays sorting


【解决方案1】:

由于没有效率限制:

  1. 将 i 设置为 0。
  2. 在未排序的元素中寻找最小值。
  3. 将其插入位置i,移动数组。
  4. 增加 i.
  5. 重复 M 次。

复杂度为 O(N * M)。

【讨论】:

  • 那是插入排序。他列举了几个他需要使用的排序实现;这是其中之一。
  • @Servy 我还要求提供其中一种算法,只是为了了解这怎么可能。我不需要每种方法的解释 :) 我现在就试试这个。
  • 作为气泡的提示,在您第一次通过时,您还可以扫描最低的 M 元素,将它们记住在列表或数组中,并且在任何进一步的扫描中,仅在至少一个时执行交换正在交换的元素在该列表中。这应该只是放入一个知道它在没有执行交换时完成的实现。
【解决方案2】:

没有看到您的实现,这很难回答。有很多方法可以做到这一点,而且大多数都是直截了当的。

这里有一些想法:

  1. 创建一个“临时”数组,只保存要排序的数字,对其进行排序,然后替换为原始数组(可能是次优解决方案)
  2. 使用 for 循环迭代您需要的次数(3 次或其他次数)。这可能是最好的解决方案
  3. 在 SO 上发布您的代码,一些天真的人可能会给您一个解决方案,这样您就不必自己做功课了。 (这是一个懒惰且不合时宜的解决方案)

【讨论】:

    【解决方案3】:

    我想这就是你要找的,这是一个基于特定索引的数组升序排序示例。

            int startIndex=2;
            int endIndex=5;
            int[] elements=new int[7];
            elements[0]=2; 
            elements[1]=9;
            elements[2]=8;
            elements[3]=3;
            elements[4]=4;
            elements[5]=15;
            elements[6]=11;
            for (int a=startIndex-1;a<endIndex;a++){
                for(int b=startIndex-1;b<endIndex;b++){
                    if (elements[a]<elements[b]){
                        int temp =elements[a];
                        elements[a]=elements[b];
                        elements[b]=temp;
                    }
                }
            }
            for (int c=0;c<elements.Length;c++){
                Console.Write(elements[c]+",");
            }
    

    如果你想对它进行降序排序,只需将“”即可。

    【讨论】:

      【解决方案4】:

      您想看看您需要使用哪种排序算法。例如,我们正在使用一个使用 for 循环的方法。大多数情况下你会看到这样的东西

      for(int i = 0; i

      在您的情况下,只需更改 for 循环的参数

      for(int i = 0; i

      其中 M 小于 arrayName.length();并且是您想要排序的从头开始的位置数。

      数组的其余部分保持不变。

      【讨论】:

      • 如果你看这个例子,不是源数组的前 N ​​项被排序,而是完全排序的数组的前 N ​​项应该被正确排序。
      • 这不符合要求。 OP 想要对数组的 M smallest 元素进行排序,而不是 M first
      • @Chris & Konrad。对于插入排序、冒泡排序和选择排序,它们是相同的。循环的每次迭代将一项移动到数组的前面。不过,这对于快速排序不太适用,这将是一个稍微不同的修改。显然它在一般情况下不起作用;它只是碰巧适用于 OP 的几乎所有情况。
      【解决方案5】:

      几件事。大多数排序算法使用 array.length 作为最大范围。 你可以用 m 代替吗?即

      for (int i = 0; i < m; i++)
      

      此外,您可以使用前 m 个字符的临时数组,对其进行排序,然后重新分配。

      int[] temp; 
      for (int i = 0; i < m; i++)
      {
          temp[i] = realArray[i]; 
      }
      //sort, then
      for (int i = 0; i < m; i++)
      {
          realArray[i] = temp[i]; 
      }
      

      【讨论】:

        【解决方案6】:

        我会对整个数组进行排序并将其放入另一个数组中。

        截断新数组以仅保留最小的 x 元素。 从该数组中获取最大的数字(在您的示例中为 4)。

        循环遍历初始数组并附加所有更高的数字。


        输入:2 9 8 3 4 15 11
        全部排序:2 3 4 8 9 11 15
        截断:2 3 4

        从该数组中获取最高值 (4)
        循环遍历原始数组并追加

        2 比 4 高吗?没有
        9比4高吗?是的,追加(我们现在有:2 3 4 9)
        8比4高吗?是的,追加(我们现在有:2 3 4 9 8)
        3比4高吗?没有
        4比4高吗?没有
        15比4高吗?是的,追加(我们现在有:2 3 4 9 8 15)
        11比4高吗?是的,追加(我们现在有:2 3 4 9 8 11)

        *这不是最有效的方法,如果你有重复的数字可能会导致问题

        【讨论】:

          【解决方案7】:

          关于使用 LINQ 的任何规定?

          int a[] = new int[] {2, 9, 8, 3, 4, 15, 11}; 
          const int M = 5;
          a = a.Take(M).OrderBy(e => e).ToArray(); // EDIT: Added .ToArray()
          

          【讨论】:

          • 那一定是作弊哈
          • @Earlz,是的,但使用 SO 也是如此。感谢您的支持,我刚刚破了 9000。
          • 尝试执行这个;它不会产生所需的输出。
          • 显然 OP 在问题中写了一件事,但想要一些完全不同的东西。
          • @Magnus - 感谢您的支持。这是一个轻松的回答。
          猜你喜欢
          • 1970-01-01
          • 2012-05-24
          • 1970-01-01
          • 2013-06-27
          • 2019-04-10
          • 2013-12-03
          • 2010-09-15
          • 1970-01-01
          • 2020-06-09
          相关资源
          最近更新 更多