【问题标题】:Bubble sort worst case example is O(n*n), how?冒泡排序最坏的例子是 O(n*n),怎么样?
【发布时间】:2023-04-01 19:25:01
【问题描述】:

我正在尝试冒泡排序。有 5 个元素,数组未排序。冒泡排序的最坏情况应该是 O(n^2)。

作为一个例子,我正在使用

A = {5, 4, 3, 2, 1}

在这种情况下,比较应该是 5^2 = 25。 使用手动验证和代码,我得到的比较计数是 20。 以下是冒泡排序实现代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SortingAlgo
{
class Program
{
    public static int[] bubbleSort(int[] A)
    {
        bool sorted = false;
        int temp;
        int count = 0;
        int j = 0;
            while (!sorted)
            {
                j++;
                sorted = true;
                for (int i = 0; i < (A.Length - 1); i++)
                {
                    count++;
                    if(A[i] > A[i+1])
                    {
                        temp = A[i];
                        A[i] = A[i+1];
                        A[i+1] = temp;
                        sorted = false;
                    }

                    Console.Write(count + ". -> ");
                    for(int k=0; k< A.Length; k++)
                    {
                        Console.Write(A[k]);
                    }
                    Console.Write("\n");

                }                
            }
      return A;

    }

    static void Main(string[] args)
    {
        int[] A = {5, 4, 3, 2, 1};
        int[] B = bubbleSort(A);
        Console.ReadKey();
    }
   } 
  }

输出如下

  1. -> 45321
  2. -> 43521
  3. -> 43251
  4. -> 43215
  5. -> 34215
  6. -> 32415
  7. -> 32145
  8. -> 32145
  9. -> 23145
  10. -> 21345
  11. -> 21345
  12. -> 21345
  13. -> 12345
  14. -> 12345
  15. -> 12345
  16. -> 12345
  17. -> 12345
  18. -> 12345
  19. -> 12345
  20. -> 12345

知道为什么数学不是 25 吗?

【问题讨论】:

    标签: c# algorithm


    【解决方案1】:

    Big-O 符号不会告诉您算法需要多少次迭代(或多长时间)。它表示随着元素数量的增加(通常趋向于无穷大),函数的增长率 rate

    因此,在您的情况下,O(n2) 仅表示冒泡排序的计算资源随着元素数量的增加而增加。所以,如果你有两倍多的元素,你可以期望它(最坏的情况)需要 4 倍的时间(作为 upper 界限)。如果您有 4 倍的元素,则复杂性会增加 16 倍。等等。

    对于复杂度为 O(n2) 的算法,五个元素可能需要 25 次迭代,即 25,000 次迭代。不分析算法就无法判断。同样,具有 O(1) 复杂度(恒定时间)的函数可能需要 0.000001 秒来执行或两周来执行。

    【讨论】:

    • 最重要的部分是当你加倍N时,预期的操作数会增加四倍。 Big-O 不是关于操作的确切数量,而是关于数量如何随问题大小而变化。
    • 差不多。当你将 N 加倍时,如果 N > N_0,则操作数增加不超过四倍。
    • @Ken - 实际上,这不是真的。大 O 表示法 表示 N 趋于无穷大时的极限。
    【解决方案2】:

    如果算法采用n^2 - n 操作,则仍会简化为O(n^2)。 Big-O 表示法只是算法扩展方式的近似值,而不是对特定输入需要多少操作的精确测量。

    【讨论】:

      【解决方案3】:

      考虑:您的示例,对 5 个元素进行冒泡排序,需要 5x4 = 20 次比较。这概括为对 N 个元素进行冒泡排序需要 N x (N-1) = N^2 - N 比较,并且 N^2 很快就会比 N 大很多。这就是 O(N^2) 的来源。 (例如,对于 20 个元素,您正在查看 380 次比较。)

      【讨论】:

        【解决方案4】:

        冒泡排序是一种特殊情况,它的完整复杂度是 (n*(n-1)) - 它给出了正确的数字:5 个元素导致 5*(5-1)操作数,即 20,是您在最坏情况下发现的。

        然而,简化的Big O notation 删除了常数和最不显着增长的项,只给出了 O(n^2)。这使得很容易将其与可能不完全具有 (n*(n-1)) 的其他实现和算法进行比较,但简化后显示工作如何随着更大的输入而增加。

        比较大 O 表示法要容易得多,对于大型数据集,常数和较小的项可以忽略不计。

        【讨论】:

        • 没有“完整”大 O 和“简化”大 O - 根据大 O 的定义,O(n^2) 等价于 O(n(n-1))。如果您正在谈论它需要多少次迭代,那么您就不再使用大 O 表示法了。
        • 没错,但对于初学者来说,区别就很模糊了。我将对其进行编辑以更正式地正确。
        【解决方案5】:

        记住 O(N^2) 是从 C * N(2) 的实际表达式简化而来的;也就是说,有一个有界常数。例如,对于冒泡排序,C 大约是 1/2(不完全是,但接近)。

        您的比较次数也减少了,我认为应该是 10 次成对比较。但我想你可以考虑交换元素是另一种。无论哪种方式,所做的只是改变常数,而不是更重要的部分。

        【讨论】:

        • O(N^2) 声明存在一个 C 为所有 N 提供这样一个上限。当您说“C 大约为 1/2”时,您似乎在谈论满足 C 条件的最小可能数。事实上,对于给定算法,可能不存在最小可能 C - 满足该属性的实数集可能在下面打开。冒泡排序是最坏的情况 n(n-1)/2 比较,不是吗?在这种情况下,最小可能的 C 确实存在,并且正好是 1/2。
        • 是的,我认为你的总结是正确的——我特别指的是冒泡排序的情况,以及为什么它不完全是 n*n (因为在最坏的情况下只需要其中的一半;和对于已排序数组的最优情况,即 n,更少)。
        【解决方案6】:
        for (int i=4; i>0; i--) {     
            for (int j=0; j<i;j++) {
                if (A[j]>A[j+1]){
                swapValues(A[j],A[j+1]);
                    ................
        

        5 (0:4) 个元素的比较计数应为 10。

        i=4 - {(j[0] j[1]) (j[1] j[2]) (j[2] j[3]) (j[3] j[4])} - 4 comparisons
        i=3 - {(j[0] j[1]) (j[1] j[2]) (j[2] j[3])} - 3 comparisons
        i=2 - {(j[0] j[1]) (j[1] j[2])} - 2 comparisons
        i=1 - {(j[0] j[1])} - 1 comparison
        

        【讨论】:

          猜你喜欢
          • 2012-07-13
          • 2022-01-11
          • 1970-01-01
          • 2013-01-28
          • 2012-09-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-01-25
          相关资源
          最近更新 更多