【问题标题】:Why is performance of bubble sort and insertion sort same i.e O(n^2)为什么冒泡排序和插入排序的性能相同,即 O(n^2)
【发布时间】:2013-07-09 10:04:48
【问题描述】:

我执行了以下代码来检查冒泡排序和插入排序所需的迭代次数和交换次数。即使(参考下面的代码)与冒泡排序相比,插入排序实际上做了一半的迭代和相同数量的交换,但是为什么两者都具有相同的 BIG-O 复杂度

static void bubbleSortExample()
    {
        int iterationCount=0;
        int swaps=0;
        int [] arr={2,6,1,4,8,7,10,3};
        int temp=0;
        for(int i=0; i< arr.length; i++)
        {
            iterationCount=iterationCount+1;
            for(int j=0; j<arr.length-1; j++)
            {
                iterationCount=iterationCount+1;
                if(arr[j]> arr[j+1])
                {
                    swaps= swaps+1;
                    temp= arr[j+1];
                    arr[j+1]= arr[j];
                    arr[j]= temp;
                }
            }
        }
        System.out.println("Bubble Sort----Iteration count are : " + iterationCount + " and swaps are : " + swaps);
    }
    //Bubble Sort Example Ends


    //Insertion Sort Example Starts
    static void insertionSortExample()
    {
        int iterationCount=0;
        int swaps=0;
        int [] arr={2,6,1,4,8,7,10,3};

        for(int i=1;i< arr.length;i++)
        {
            iterationCount=iterationCount+1;
            int key=arr[i];// this is the number that needs to be inserted in its correct position
            for(int j=i-1; j >= 0;  j--)
            {
                iterationCount=iterationCount+1;
                if(key < arr[j])
                {
                    swaps= swaps+1;
                    int t= arr[j];
                    arr[j]=key;
                    arr[j+1]=t;

                }
            }
        }
        System.out.println("Insertion Sort----Iteration count are : " + iterationCount + " and swaps are : " + swaps);
    }

输出

Bubble Sort----Iteration count are : 64 and swaps are : 9
Insertion Sort----Iteration count are : 35 and swaps are : 9

【问题讨论】:

  • Big-O 描述了随着输入大小增加的行为。您的测试仅包含一个固定大小的数组,因此与 Big-O 分析无关。此外,在 Big-O 分析中忽略了常数因素,因此插入排序很有可能只执行“字面上一半”的操作,同时仍然具有与冒泡排序相同的 Big-O 复杂度。

标签: algorithm big-o


【解决方案1】:

哇!哇!等等。你混淆了两件事。
一个是运行时间,它是程序在输入实例上的实际运行时间。
其次是时间复杂度,即运行时间如何随着输入大小的增长而增长。

在实践中,O(N^2) 的程序可以比 O(NlogN) 的代码运行得快得多。这是因为输入可能大部分是平均情况,但是 Big-Oh 分析仅适用于最坏情况分析。这是因为 Big-Oh 没有说明实际运行时间(这可能取决于输入的性质(最佳情况/最坏情况),实际实施的细节)。Big-Oh 只给我们一个保证 算法的运行不会比该函数的常数倍差。

您可以阅读我的回答 here 来澄清这些。

所以当我们说冒泡排序/插入排序是 O(N2) 时,我们的意思是说最坏情况下的运行时间不大于常数倍 N^2 .意识到这确实是两种算法的情况。

如果您仍有困惑,请随时提问。

【讨论】:

  • 你解释得很好,谢谢。你能指点我一些文章/书,我可以在其中阅读更多关于算法和计算其复杂性的信息
  • 我一直找不到好文章,最好的办法是自己解决,如果有问题可以在这里提问。我就是这么学习的。或者如果你有数学倾向,你可以阅读 CLRS 中的部分(书名:算法简介)
  • 其实你经常会发现人们通过符号来分析Worst Case、Best Case和Average Case。不过很好的说明。
  • Big-Oh 是一种通用表示法,可用于描述任何输入情况,但在使用时应该理解它的含义。虽然它是一种经常被误解的表示法,但确实如此.
【解决方案2】:

请记住,该符号仅表示算法在 n 增长时的行为方式。一个线性因子总是从中删除。所以它实际上并没有说明算法是否很快,它只是说明随着 n 的增加需要更多时间来完成的因素。

【讨论】:

    【解决方案3】:

    在第 i 次迭代的冒泡排序中,您总共有 n-i-1 次内部迭代 (n^2)/2,但在插入排序中,您在第 i 步有最大 i 次迭代,但平均为 i/2,您可以在找到当前元素的正确位置后,尽早停止内部循环。

    所以你有(从 0 到 n 的总和)/2,即 (n^2)/4 总计;

    这就是插入排序比冒泡排序快的原因。

    【讨论】:

    • 我不是在争论插入排序是否更快,我问的是如果交换次数相似,它是否更快,那么为什么两者都有相似的 BIG-O
    • 这可能会让您感到困惑,因为您对 BIG-O 的含义有一个错误的认识。
    猜你喜欢
    • 2012-07-13
    • 2013-01-28
    • 2022-01-11
    • 2011-11-30
    • 2015-09-12
    • 1970-01-01
    • 2015-04-25
    • 2014-12-11
    • 1970-01-01
    相关资源
    最近更新 更多