我遇到了一个非常快速的冒泡排序算法......就像快速排序的逆序排序一样排序100,000个全长整数。我知道冒泡排序被认为是最低效的排序算法之一,那么是什么让这个更好?
我看到如果第一遍没有交换任何项目(意味着它已经排序),它会停止排序,但这不会影响逆序案例。
P.S。任何人都可以想到一种方法来更快地排序这么多的整数?也许Radix排序?
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;
}
}
}
}
答案 0 :(得分:3)
评论说它是comb sort。
对于就地排序,quick sort或heap sort会更快。如果使用第二个临时数组,则merge sort或counting / radix sort会更快。计数/基数排序应该是最快的。
计数/基数排序的示例代码。我的系统需要大约0.001秒(Intel 2600K,3.4ghz)。这个示例代码可以稍微优化一下(比如使用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);
}
答案 1 :(得分:1)
虽然它与冒泡排序有相似之处,但我认为这是一个shell sort,这是冒泡排序的一个更快的变种。