我有一个类似于
的quick_sort代码(С++)template< typename BidirectionalIterator, typename Compare >
BidirectionalIterator quick_sort_partition( BidirectionalIterator left, BidirectionalIterator right, Compare cmp ) {
BidirectionalIterator q = left - 1;
std::mt19937 gen(time(0));
std::uniform_int_distribution<int> uid(0, right - left - 1);
int pivot_1 = uid(gen) ;
BidirectionalIterator randomNum = pivot_1 + left;
std::iter_swap( randomNum, right );
bool index = 0;
for (BidirectionalIterator i = left; i < right; i++){
if (*i < *right){
++q;
std::iter_swap( q, i );
}
if (*i == *right){
index = 1 - index;
if(index){
++q;
std::iter_swap( q, i );
}
}
}
++q;
std::iter_swap( q, right );
return q;
}
template< typename BidirectionalIterator, typename Compare >
void quick_sort( BidirectionalIterator first, BidirectionalIterator last, Compare cmp ) {
if (first < last){
BidirectionalIterator q = quick_sort_partition(first, last, cmp);
quick_sort(first, q - 1, cmp);
quick_sort(q + 1, last, cmp);
}
}
但他在大考试中比std :: sort慢(多6次)。
任何想法为什么?
如何优化我的代码以获得好工作?
答案 0 :(得分:3)
您的QuickSort实施非常普遍。它确实使用随机数据透视选择,这确保没有导致性能降级的“杀手”输入,因此它比绝对基本的QuickSort更好。
可以使用许多优化,其中包括:
“快速排序”通常实际上是作为混合排序实现的,它可以回退到(例如)插入排序小于某个固定阈值的分区。一旦进入小分区,Quick Sort的开销往往会克服其渐近的复杂性优势。
可以通过切换到混合递归/迭代方法来最小化最大递归深度并且可以减少函数调用开销,其中在每次分区时,递归地对较小的子数组进行排序,但是代码只是循环以进行排序较大的一个。
分区时,您可以通过查找交换将两者放在正确的子分区中的元素对来减少交换次数,并交换这些元素,而不是交换交换到一个子分区并交换到另一个子分区。
在整个排序过程中重新使用相同的随机数源可能会有所帮助,而不是在每次分区时实例化一个新的。