我一直在寻找最快的算法来排序1,000,000个整数。到目前为止,令人惊讶的是,C内置的qsort函数似乎是我尝试的任何东西中最快的(我已经测试了预排序,反向排序和随机输入文件)。平均而言,我获得了大约.07秒的预先和反向排序和.2秒的随机。
如何优化它以更快地运行?有没有快速的技巧?我知道C ++的std排序更快,但不能在C中使用...我附上了我的代码。
int compare(const void *x, const void *y){
return ( *(int*)x >= *(int*)y );
}
qsort(list, 1000000, sizeof(int), compare);
答案 0 :(得分:1)
此计数/基数排序将在我的系统(Intel 2600K 3.4ghz)上在大约0.01秒内对1,000,000个32位无符号整数进行排序,但它使用与原始数组(pData)大小相同的第二个数组(pTemp),所以它需要两倍的内存。
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);
}
对于有符号整数,只需要在用于索引时对整数的符号位进行补码:
typedef int I32;
typedef unsigned int UI32;
I32 * RadixSort(I32 * pData, I32 * 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++){
if(j != 3) // signed integer handling
mIndex[j][(size_t)(u & 0xff)]++;
else
mIndex[j][(size_t)((u^0x80) & 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 = (UI32 *)pTemp; // radix sort
pSrc = (UI32 *)pData;
for(j = 0; j < 4; j++){
for(i = 0; i < count; i++){
u = pSrc[i];
if(j != 3) // signed integer handling
m = (size_t)(u >> (j<<3)) & 0xff;
else
m = (size_t)((u >> (j<<3))^0x80) & 0xff;
pDst[mIndex[j][m]++] = u;
}
pTmp = pSrc;
pSrc = pDst;
pDst = pTmp;
}
return((I32 *)pSrc);
}