【问题标题】:why is the time complexity of bubble sort's best case being O(n)为什么冒泡排序最佳情况的时间复杂度是 O(n)
【发布时间】:2012-09-12 10:02:31
【问题描述】:

我根据ALGORITHMS 2.2一书中使用的方法推导出了冒泡排序在最佳情况下的时间复杂度。但结果却是 O(n^2)。

这是我的推导,希望有人能帮我找出错误的地方:

public void bubbleSort(int arr[]) {
for(int i = 0, len = arr.length; i < len - 1; i++) {
    for(int j = 0; j < len - i - 1; j++) {
        if(arr[j + 1] < arr[j])
            swap(arr, j, j + 1);
    }
}

}

Statements                      cost    times
i = 0,len = arr.length          c1          1
i < len - 1                     c2          n
i++                             c3          n - 1
j = 0                           c4          n - 1
j < len - i - 1                 c5          t1(i=0) + t1(i=1) + ... + t1(i = n-2)
j++                             c6          t2(i=0) + t2(i=1) + ... + t2(i = n-2)
arr[j + 1] < arr[j]             c7          t3(i=0) + t3(i=1) + ... + t3(i = n-2)
swap(arr, j, j + 1)             c8          t4(i=0) + t4(i=1) + ... + t4(i = n-2)

T(n) = c1 + c2n + c3(n - 1) + c4(n - 1) + c5t5 + c6t6 + c7t7 + c8t8 = c1 + c2n + c3(n - 1) + c4(n - 1) + c5[t1(i=0) + t1(i=1) + ... + t1(i = n-2)] + c6 [t2(i=0) + t2(i=1) + ... + t2(i = n-2)] + c7[t3(i=0) + t3(i=1) + ... + t3 (i = n-2)] + c8[t4(i=0) + t4(i=1) + ... + t4(i = n-2)];

在最佳阵容中,序列在排序之前已经是正数。那么 t8 应该是 0。

T(n) = c1 + c2n + c3(n - 1) + c4(n - 1) + c5[t1(i=0) + t1(i=1) + ... + t1(i = n-2)] + c6[t2(i=0) + t2(i=1) + ... + t2(i = n-2)] + c7[t3(i=0) + t3(i=1 ) + ... + t3(i = n-2)]

时间复杂度为O(n^2)

【问题讨论】:

    标签: time-complexity bubble-sort


    【解决方案1】:

    冒泡排序的最佳情况是元素已经排序。

    通常的实现为最佳、平均、最坏情况给出 O(n^2) 时间复杂度。

    我们可以通过在每次迭代时检查数组是否已排序(交换表示未排序的数组)来修改冒泡排序。

    一旦发现数组被排序(如果没有交换发生)控制退出循环或循环继续执行直到长度为1。

    插入排序也是如此!

    【讨论】:

      【解决方案2】:

      我不确定你在数什么。一般来说,当您谈论比较排序算法时,您应该计算所进行的比较次数。冒泡排序就是这样认为的。在这种情况下,您提出的算法是 O(n^2)。

      如果你计算交换次数,它的 O(1) 甚至可能会说 O(0)。然而,像这样分析冒泡排序是很少见的。

      但是,您可以非常轻松地改进 Bubble 以在最佳情况下获得 O(N)。例如,通过引入标志 swap_was_made。如果它在内部for 的末尾为假,您可以完成。在最好的情况下,它将复杂性降低到 O(N)(一个内部 for 循环)。在公平均匀分布的情况下,它将预期或平均复杂度降低到 O(N^2/2) ......但请仔细检查我可能是错的。这里没有做数学。

      【讨论】:

        【解决方案3】:

        你的实现

        public void bubbleSort(int arr[]) {
            for(int i = 0, len = arr.length; i < len - 1; i++) {
                for(int j = 0; j < len - i - 1; j++) {
                    if(arr[j + 1] < arr[j])
                        swap(arr, j, j + 1);
                }
            }
        }
        

        缺乏控制内循环是否有任何交换,如果没有,则退出外循环。

        这种控制使得最好的情况(一个已经排序的数组)可能是 O(n),因为当它第一次运行时,内部循环中没有交换。

        public void bubbleSort(int arr[]) {
            boolean swapped = true;
            for(int i = 0, len = arr.length; swapped && i < len - 1; i++) {
                swapped = false;
                for(int j = 0; j < len - i - 1; j++) {
                    if(arr[j + 1] < arr[j]) {
                        swap(arr, j, j + 1);
                        swapped = true;
                    }
                }
            }
        }
        

        【讨论】:

        • 不过,在分析算法时,最好不要假设除了基本实现之外的任何东西。在这种情况下,我们必须假设冒泡排序不会被实现为一个优化版本,如果它从不交换任何值就会中断循环。
        • @AleksandrH 是的。但是对于冒泡排序,至少有一些作者(例如wikipedia)在定义中包含了检查。
        猜你喜欢
        • 2013-01-28
        • 1970-01-01
        • 2013-02-21
        • 2012-07-13
        • 1970-01-01
        • 2021-04-11
        • 2018-02-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多