【问题标题】:Logic behind a bubble sort冒泡排序背后的逻辑
【发布时间】:2012-11-24 06:55:57
【问题描述】:

我正在做一个冒泡排序练习,我的感觉是它非常接近正确。 就像现在一样,我看到了一个永恒的循环。

错在哪里?

static void Main(string[] args)
    {
        int[] numbers = { 2, 4, 8, 5, 88, 55, 32, 55, 47, 8, 99, 120, 4, 32 };
        int temporary;
        bool sorted;
        do
        {
            sorted = false;

            for (int i = 0; i < numbers.Length - 1; i++)
            {
                int a = numbers[i];
                int b = numbers[i + 1];
                if (a > b)
                {
                    temporary = a;
                    a = b;
                    b = temporary;

                    sorted = true;

                }
            }
            Console.WriteLine("sorted");
        } while (sorted == true);


        foreach (int i in numbers)
        {
            Console.Write(i + " ");
        }

    }

【问题讨论】:

  • @Killercam 我认为问题表明这是一个竞争条件。
  • 酷。向所有人道歉... :'[
  • 您的循环总是在每次迭代中运行 1 到多次(以及该堆栈)。每次迭代都需要将结束条件减少 1。因此,您应该编写变量(具有 numbers.length)并在条件下编写 i

标签: c# bubble-sort


【解决方案1】:

C# 中更好的方法是使用通用冒泡排序

public void BubbleSort<T>(IList<T> list);
{
    BubbleSort<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;
        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++;
    }
}

Jon Skeet 在其answer here 中对该算法进行了简要说明。 “它使用任意比较器,但允许您省略它,在这种情况下,默认比较器用于相关类型。它将对 IList 的任何(非只读)实现进行排序,其中包括数组。”

我希望这会有所帮助。

【讨论】:

  • 仿制药+1,但是!算法正在浪费时间检查已经排序的“最终”对象。泡泡被称为“泡泡”,因为他总是将最大的数字推到最右边。因此,无需为每次迭代反复检查。将 'Length' 存储到变量中,并且 -- 它在条件中。
  • 请检查this improved versionJon Skeet的算法。
  • 酷。已编辑。感谢您的宝贵时间。
【解决方案2】:

您将ab 交换,但您不对输入数组做任何事情。因此,您不断地在内存中交换值,但原始数组没有改变。试试:

            for ( int i = 0; i < numbers.Length - 1; i++ )
            {
                if ( numbers[i] > numbers[i + 1] )
                {
                    temporary = numbers[i];
                    numbers[i] = numbers[i + 1];
                    numbers[i + 1] = temporary;

                    sorted = true;

                }
            }

【讨论】:

    【解决方案3】:

    您没有将结果写回数组。

    改用这个:

    //temporary = a;
    //a = b;
    //b = temporary;
    
    numbers[i] = b;
    numbers[i + 1] = a;
    

    【讨论】:

    • 如果我可以补充,请检查值类型和引用类型之间的区别。
    【解决方案4】:

    应该是

    if (numbers[i] > numbers[i + 1])
        {
                temporary = numbers[i];
                numbers[i] = numbers[i + 1];
                numbers[i + 1] = temporary;
    
                sorted = true;
    
         }
    

    a,b 中所做的更改不会反映在numbers[i] numbers[i+1] 中,因为a 和b 只是copy 中的numbers[i] numbers[i+1]..

    【讨论】:

      【解决方案5】:

      这是一个工作示例:

      static void Main(string[] args)
      {
          int[] numbers = { 2, 4, 8, 5, 88, 55, 32, 55, 47, 8, 99, 120, 4, 32 };
          int temporary;
          bool sorted;
      
          do
          {
              sorted = false;
              for (int i = 0; i < numbers.Length - 1; i++)
              {
                  if (numbers[i] > numbers[i + 1])
                  {
      
                      temporary = numbers[i];
                      numbers[i] = numbers[i + 1];
                      numbers[i + 1] = temporary;
      
                      sorted = true;
                  }
              }
              Console.WriteLine("sorted");
          } while (sorted == true);
      
          foreach (int i in numbers)
          {
              Console.Write(i + " ");
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-20
        • 1970-01-01
        • 1970-01-01
        • 2013-10-09
        • 2017-03-11
        • 2015-09-12
        相关资源
        最近更新 更多