对算法进行一些更新。我写了这个快速排序实现:
#define SWAP(X, Y, Type) { Type Temp = (X); (X) = (Y); (Y) = Temp; }
int QSPartition(int* Array, int StartIndex, int EndIndex)
{
int PivotDestinationIndex = StartIndex;
int Pivot = Array[EndIndex];
for(int i = StartIndex; i <= EndIndex; i++)
{
if (Array[i] < Pivot)
{
SWAP(Array[i], Array[PivotDestinationIndex], int);
PivotDestinationIndex++;
}
}
SWAP(Array[PivotDestinationIndex], Array[EndIndex], int);
return PivotDestinationIndex;
}
void QuickSort(int* Array, int StartIndex, int EndIndex)
{
if (StartIndex >= EndIndex)
return;
int PivotIndex = QSPartition(Array, StartIndex, EndIndex);
QuickSort(Array, PivotIndex + 1, EndIndex);
QuickSort(Array, StartIndex, PivotIndex - 1);
}
在我的主程序中:
#define Measure(Iterations, What, Code)\
{\
clock_t Begin = clock();\
for(int _im_ = 0; _im_ < Iterations; _im_++)\
{\
Code;\
}\
clock_t End = clock();\
printf("Time took to " What ": %.1f ms\n", (double)(End - Begin));\
}
int CompareInt(const void* x, const void* y) { return *(int*)x - *(int*)y; }
int main()
{
srand(time(0));
int Count = 100000;
int* Array0 = (int*)malloc(sizeof(int) * Count);
int* Array1 = (int*)malloc(sizeof(int) * Count);
for (int i = 0; i < Count; i++)
{
int RandomValue = rand() % 100;
Array0[i] = RandomValue;
Array1[i] = RandomValue;
}
Measure(1, "My Quick", QuickSort(Array0, 0, Count - 1));
Measure(1, "C Quick", qsort(Array1, Count, sizeof(int), CompareInt));
getchar();
return 0;
}
输出结果是“我的快速”始终在125 ms
左右,而“C快速”始终在25 ms
左右。 (32位DEBUG构建 - 在RELEASE上仍然相同,慢5倍)
发生了什么事?为什么我的实现速度较慢? (我尝试了内联函数,但没有做太多的事情)还有其他错误吗? (我计算时间的方式,或者我用随机值填充数组的方式,还是......?)
答案 0 :(得分:2)
尝试其中一个,你需要将std :: swap更改为交换C。
使用枢轴中间值的QuickSort:
void QuickSort(uint32_t a[], int lo, int hi) {
int i = lo, j = hi;
uint32_t pivot = a[(lo + hi) / 2];
while (i <= j) { // partition
while (a[i] < pivot)
i++;
while (a[j] > pivot)
j--;
if (i <= j) {
std::swap(a[i], a[j]);
i++;
j--;
}
}
if (lo < j) // recurse
QuickSort(a, lo, j);
if (i < hi)
QuickSort(a, i, hi);
}
QuickSort使用低,中,高值的中位数作为支点
void QuickSort(uint32_t a[], int lo, int hi) {
int i = lo, j = (lo + hi)/2, k = hi;
uint32_t pivot;
if (a[k] < a[i]) // median of 3
std::swap(a[k], a[i]);
if (a[j] < a[i])
std::swap(a[j], a[i]);
if (a[k] < a[j])
std::swap(a[k], a[j]);
pivot = a[j];
while (i <= k) { // partition
while (a[i] < pivot)
i++;
while (a[k] > pivot)
k--;
if (i <= k) {
std::swap(a[i], a[k]);
i++;
k--;
}
}
if (lo < k) // recurse
QuickSort(a, lo, k);
if (i < hi)
QuickSort(a, i, hi);
}