【问题标题】:What's the most elegant way to bubble-sort in C#?在 C# 中进行冒泡排序最优雅的方法是什么?
【发布时间】:2010-12-08 09:22:32
【问题描述】:

这可以清理吗?

using System;  
class AscendingBubbleSort 
{     
    public static void Main()
    {
        int i = 0,j = 0,t = 0;
        int []c=new int[20];
        for(i=0;i<20;i++)
        {
            Console.WriteLine("Enter Value p[{0}]:", i);
            c[i]=int.Parse(Console.ReadLine());
        }
        // Sorting: Bubble Sort
        for(i=0;i<20;i++)
        {
            for(j=i+1;j<20;j++)
            {
                if(c[i]>c[j])
                {
                    Console.WriteLine("c[{0}]={1}, c[{2}]={3}", i, c[i], j, c[j]);
                    t=c[i];
                    c[i]=c[j];
                    c[j]=t;
                }
            }
        }
        Console.WriteLine("bubble sorted array:");
        // sorted array output
        for(i=0;i<20;i++)
        {
            Console.WriteLine ("c[{0}]={1}", i, c[i]);
        }
    }
}

【问题讨论】:

  • 优雅和冒泡排序不属于同一个句子,恕我直言。
  • 如果这是一项家庭作业,我会让代码尽可能丑陋,并在代码中乱扔垃圾,比如“故意在代码中添加令人讨厌的东西,以反映我对这个算法的厌恶”......老师会尊重你的原则。
  • 这不是冒泡排序...
  • @Ian:学习如何将算法描述转化为代码是有价值的……
  • @Ian:我认为大多数关于排序位置的讨论都提到冒泡排序这一事实表明它非常相关,即使只是针对排序的讨论。它通常不适合商业环境这一事实并不意味着它不值得讨论。

标签: c# .net arrays bubble-sort


【解决方案1】:

您粘贴的内容不是bubble sort。这是一种“蛮力”排序,但不是冒泡排序。这是一个通用冒泡排序的示例。它使用任意比较器,但允许您省略它,在这种情况下,默认比较器用于相关类型。它将对IList&lt;T&gt; 的任何(非只读)实现进行排序,其中包括数组。阅读上面的链接(维基百科),以更多地了解冒泡排序的工作原理。请注意我们在每个循环中如何从头到尾进行,但仅将每个项目与其相邻项目进行比较。它仍然是一个 O(n2) 排序算法,但在许多情况下它会比您给出的版本更快。

public void BubbleSort<T>(IList<T> list)
{
    BubbleSort<T>(list, Comparer<T>.Default);
}

public void BubbleSort<T>(IList<T> list, IComparer<T> comparer)
{
    bool stillGoing = true;
    while (stillGoing)
    {
        stillGoing = false;
        for (int i = 0; i < list.Count-1; i++)
        {
            T x = list[i];
            T y = list[i + 1];
            if (comparer.Compare(x, y) > 0)
            {
                list[i] = y;
                list[i + 1] = x;
                stillGoing = true;
            }
        }
    }
}

【讨论】:

  • @Ian:不是每个来这里的人都在做作业。有了这个答案,他们就会找到他们正在寻找的东西,并可以继续解决下一个问题。 :)
  • 我(严重)困惑为什么你认为这是一个比原来“更真实”的冒泡排序。两者都在冒泡,有不同的优化。您的版本忽略了缩小范围。
  • @Henk:看看维基百科的文章。那里描述的算法看起来像原来的吗?特别是,OP 的代码比较任意对,立即与算法描述中的“比较每对相邻项”部分背道而驰。这当然是蛮力交换排序,但不是冒泡排序。
  • 乔恩,你是对的,我误读了if(c[i]&gt;c[j]) 部分。我已经看到类似的循环在做if(c[j]&gt;c[j+1]) 并且正在冒泡。
【解决方案2】:

在 C# 中最优雅的排序方式是

Array.Sort( object[] )

除了老师要求你实现非优雅冒泡排序算法的家庭作业问题外,这在任何地方都适用。 ;-)

【讨论】:

    【解决方案3】:

    总体而言,您的冒泡排序实现没有任何问题。如果我进行真正的代码审查,我会做出以下更改:

    选择更具描述性的变量名称

    为什么你的数组被称为c

    最小化变量范围

    所有变量都在函数顶部声明。除非这是家庭作业要求或编码标准,否则将变量声明为“靠近”它们使用的位置会更惯用,最好是它们的范围尽可能小。

    因此,删除读取int i = 0,j = 0,t = 0; 的第一行。内联声明循环计数器:

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

    并在它使用的地方声明你的临时变量:

                    Console.WriteLine("c[{0}]={1}, c[{2}]={3}", i, c[i], j, c[j]);
                    int t=c[i];
                    c[i]=c[j];
                    c[j]=t;
    

    消除硬编码的数组边界。

    这个:

    for(i=0;i<20;i++)
    

    变成这样:

    for(i = 0; i < c.Length; i++)
    

    【讨论】:

      【解决方案4】:

      大多数人不会费心让冒泡排序变得优雅。不过,在一般中,我发现这样做:

      for (int i = 0; i < items.Length; i++) {
          Item item = items[i];
          // do something with item
      }
      

      比这样做更优雅,更易于维护:

      Item item;
      int i;
      for (i = 0; i < items.Length; i++) {
          item = items[i];
          // do something with item
      }
      

      换句话说,在最小的适用范围内声明您的变量。否则,您可能会发现自己在代码中的其他位置使用 iitem 做一些事情,然后在不应该出现的地方再次使用它们。

      【讨论】:

        【解决方案5】:
        • 我会使用交换方法来交换两个数组项。 (关于如何编写swap方法的细节留作功课!)

        • 你应该考虑一下物品已经有序的情况

        • 您应该阅读插入排序以获得更多标记:-)

        • 不如从键盘读取测试数据,看看能不能学会使用nUnit

        【讨论】:

        • 伊恩,我投了赞成票,因为你关于交换方法的观点是有效的。仅供参考,有人添加了作业标签,但我要求这样做是为了说明工作。
        【解决方案6】:

        我个人更喜欢这个:

        string foo [] = new string[] {"abc", "def", "aaa", "feaf", "afea" };
        Array.Sort(foo);
        

        但这只是我。排序是一个已解决的问题,为什么要重新发明轮子?

        【讨论】:

        • 当我写这个答案时,那还不存在。但是,是的,这是家庭作业。
        • 而且,这实际上是错误的。如果您查看 MS 文档,Array.Sort 使用的是 QuickSort 而不是 BubbleSort :)
        • 当问题专门询问冒泡排序时,这很重要。
        【解决方案7】:

        我相信Jon Skeet提出的answer有改进。每次循环后,迭代次数应不包括上一次迭代中处理的最后一项。所以,这里是代码:

        public void BubbleSortImproved<T>(IList<T> list)
        {
            BubbleSortImproved<T>(list, Comparer<T>.Default);
        }
        
        public void BubbleSortImproved<T>(IList<T> list, IComparer<T> comparer)
        {
            bool stillGoing = true;
            int k = 0;
            while (stillGoing)
            {
                stillGoing = false;
                //reduce the iterations number after each loop
                for (int i = 0; i < list.Count - 1 - k; i++)
                {
                    T x = list[i];
                    T y = list[i + 1];
                    if (comparer.Compare(x, y) > 0)
                    {
                        list[i] = y;
                        list[i + 1] = x;
                        stillGoing = true;
                    }
                }
                k++;
            }
        }
        

        【讨论】:

          【解决方案8】:
          int[] array = {4,5,7,1,8};           
          
          int n1, n2;
          bool stillgoing = true;
          
          while (stillgoing)
          {
              stillgoing = false;
              for (int i = 0; i < (array.Length-1); i++)
              {                  
                  if (array[i] > array[i + 1])
                  {
                      n1 = array[i + 1];
                      n2 = array[i];
          
                      array[i] = n1;
                      array[i + 1] = n2;
                      stillgoing = true; 
                  }
              }
          }
          for (int i = 0; i < array.Length; i++)
          {
              Console.WriteLine(array[i]);
          }
          

          从 Jon skeet 那里得到了一些想法...

          【讨论】:

            【解决方案9】:
                public int[] BubbleSortInAesc(int[] input)
                {
                    for (int i = input.Length; i > 0; i--)
                    {
                        for (int j = 0; j < i-1; j++)
                        {
                            if (input[j] > input[j + 1])
                            {
                                //Swap the numbers
                                input[j] = input[j + 1]+input[j];
                                input[j + 1] = input[j] - input[j + 1];
                                input[j] = input[j] - input[j + 1];
                            }
                        }
                    }
                    return input;
                }
            

            【讨论】:

              【解决方案10】:

              我认为您的算法没问题,但我会将排序功能放在单独的类和方法中。

              【讨论】:

                猜你喜欢
                • 2010-09-21
                • 2013-03-09
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-09-12
                • 1970-01-01
                • 2013-04-18
                相关资源
                最近更新 更多