这种冒泡排序的递归实现是不是效率低下,如果可能的话如何改进?

Posted

技术标签:

【中文标题】这种冒泡排序的递归实现是不是效率低下,如果可能的话如何改进?【英文标题】:Is this recursive implementation of bubble sort inefficient, and how could it be improved if possible?这种冒泡排序的递归实现是否效率低下,如果可能的话如何改进? 【发布时间】:2021-08-23 03:41:36 【问题描述】:

昨天遇到了冒泡排序的递归实现,乍一看很优雅:

template <class T> void bubblesort_recursive(T data[], const int n)
    if(n==1) return;
    else
        bubblesort_recursive(data+1, n-1);
        if(data[1]<data[0]) swap(data[1],data[0]);
        bubblesort_recursive(data+1, n-1);
    

然而,我很快意识到它调用了递归情况两次,其时间复杂度的时间递归关系似乎遵循 T(n)=2T(n-1)+c,这导致了指数时间复杂度。但是,冒泡排序通常会导致 n^2 时间复杂度。我的分析是否有问题,或者这只是冒泡排序的低效实现?如果是后者,如何改进?

【问题讨论】:

昨天我遇到了冒泡排序的递归实现,乍一看很优雅: -- 冒泡排序没有什么优雅的地方。冒泡排序是 O(n^2) - 任何比这更快的,它不是冒泡排序。 尝试使用n=5 遍历此算法。在第二次调用bubblesort_recursive 时,您应该会看到一些明显的浪费。目前尚不清楚您的“改进”标准是什么。 “如何改进” - 不要为递归而烦恼,更不用说冒泡排序了。它有一个非常有限的可行用例。不管你给那只猪涂了多少“优雅”的口红,它仍然是一头猪。 你能分享你找到它的链接吗? 这不是冒泡排序,尽管函数名称如此。 【参考方案1】:

这会导致指数级时间复杂度。

是的。

但是,冒泡排序通常会导致 n^2 时间复杂度。

是的。

如何改进?

如果您正在寻找具有 O(?²) 复杂度的冒泡排序的递归实现,那么我们需要区分两个过程:

    一扫冒泡 对数组的较短部分重复此操作

两者都可以递归方式实现,但它们将是不同的递归:

template <class T> void bubble_recursive(T data[], const int n) 
    if (n == 1) return;
    if (data[1] < data[0]) swap(data[1], data[0]);
    bubble_recursive(data + 1, n - 1);


template <class T> void bubblesort_recursive(T data[], const int n) 
    if (n == 1) return;
    bubble_recursive(data, n);
    bubblesort_recursive(data, n-1);

您还可以添加一些冒泡排序实现所具有的提前退出功能:当冒泡的单次扫描显示不必执行交换时,我们知道数组已排序,并且可以停止在较短的部分上进行更多迭代:

template <class T> bool bubble_recursive(T data[], const int n) 
    if (n == 1) return false;
    bool must_swap = data[1] < data[0]; 
    if (must_swap) swap(data[1], data[0]);
    return bubble_recursive(data + 1, n - 1) || must_swap;


template <class T> void bubblesort_recursive(T data[], const int n) 
    if (bubble_recursive(data, n))
        bubblesort_recursive(data, n - 1);

【讨论】:

以上是关于这种冒泡排序的递归实现是不是效率低下,如果可能的话如何改进?的主要内容,如果未能解决你的问题,请参考以下文章

单行数组排序冒泡排序

冒泡排序

排序算法杂谈 —— 冒泡排序的递归实现

2.冒泡排序

常见排序算法的优化

Java实现三角形计数