【问题标题】:How is this bubble sort so fast?这种冒泡排序怎么这么快?
【发布时间】:2026-01-24 00:10:01
【问题描述】:

我遇到了一个快得离谱的冒泡排序算法......就像在 0.03 秒内快速排序 100,000 个全长整数一样。我知道冒泡排序被认为是效率最低的排序算法之一,那么是什么让这个算法变得更好呢?

我发现如果第一次没有交换任何项目(这意味着它已经排序),它会停止排序,但这不应该影响颠倒顺序的情况。

附言谁能想到一种更快地对这么多整数进行排序的方法?也许基数排序?

void sort(int list[], int n)
{
    int i; 
    int j; 
    int gap;
    int swapped = 1;
    int temp;
    gap = n;

    while (gap > 1 || swapped == 1)
    {
        gap = gap * 10 / 13;
        if (gap == 9 || gap == 10)
        {
            gap = 11;
        }
        if (gap < 1)
        {
            gap = 1;
        }
        swapped = 0;
        for (i = 0, j = gap; j < n; i++, j++)
        {
            if (list[i] > list[j])
            {
                temp = list[i];
                list[i] = list[j];
                list[j] = temp;
                swapped = 1;
            }
        }
    }
}

【问题讨论】:

  • 这可以通过使用三个连续的异或操作来加快速度,而不是在堆栈上有一个变量并使用这三个赋值语句。

标签: c algorithm sorting bubble-sort


【解决方案1】:

正如评论所说,它是comb sort

对于就地排序,quick sortheap sort 会更快。如果使用第二个临时数组,则 merge sortcounting / radix sort 更快。计数/基数排序应该是其中最快的。

计数/基数排序的示例代码。我的系统(Intel 2600K,3.4ghz)大约需要 0.001 秒。此示例代码可以进行一些优化(例如使用 mIndex[j] 的指针),但我不确定编译器是否已经在进行大部分优化,您可能会通过少量代码更改进行优化。处理器开销可能非常小,以至于内存带宽是限制因素。

typedef unsigned int UI32;

UI32 * RadixSort(UI32 * pData, UI32 * pTemp, size_t count)
{
size_t mIndex[4][256] = {0};            // index matrix
UI32 * pDst, * pSrc, * pTmp;
size_t i,j,m,n;
UI32 u;

    for(i = 0; i < count; i++){         // generate histograms
        u = pData[i];
        for(j = 0; j < 4; j++){
            mIndex[j][(size_t)(u & 0xff)]++;
            u >>= 8;
        }       
    }
    for(j = 0; j < 4; j++){             // convert to indices
        n = 0;
        for(i = 0; i < 256; i++){
            m = mIndex[j][i];
            mIndex[j][i] = n;
            n += m;
        }       
    }

    pDst = pTemp;                       // radix sort
    pSrc = pData;
    for(j = 0; j < 4; j++){
        for(i = 0; i < count; i++){
            u = pSrc[i];
            m = (size_t)(u >> (j<<3)) & 0xff;
            pDst[mIndex[j][m]++] = u;
        }
        pTmp = pSrc;
        pSrc = pDst;
        pDst = pTmp;
    }

    return(pSrc);
}

【讨论】:

  • 如果仍然是 O(n^2) 算法,它如何能够在 0.03 秒内对 100,000 个元素进行排序?基数或计数真的能比 0.03 快那么多吗?
  • 您介意让我看看您使用的基数的实现吗?
【解决方案2】:

虽然它与冒泡排序很相似,但我认为这是 shell sort,它是冒泡排序的一个更快的变体。

【讨论】:

  • 啊好吧,它的标题是improved_bubble,所以我认为它是某种类型的冒泡排序
  • 最坏情况下它仍然是 O(n^2) 排序,就像冒泡排序一样,但是安排最坏情况排序要困难得多,因此在实践中它的运行速度更快。