Quick Sort篇

来源:互联网 发布:饮食通软件 编辑:程序博客网 时间:2024/06/05 03:08

Quick Sort是目前已知的最快的排序法,平均复杂度为O(NlogN),最坏的情况下将达O(N2);不过(极类似median-of-three QuickSort的一种排序算法)可将最坏情况推进到O(logN)。早期的STL sort算法都是采用Quick Sort,SGI STl以采用IntroSort。

Quick Sort算法可以叙述如下。假设S代表将被处理的序列:

1、如果S的元素个数为0或1,结束。

2、取S中的任何一个元素,当作枢纽v。

3、将S分割为L,R两段,使L内的每一个元素都小于或等于v,R内的每一个元素都大于或等于v。

4、对L,R递归执行Quick Sort。

Quick Sort的精神在于将大区间分割为小区间,分段排序。每一个小区间排序完成后,串接起来的大区间也就完成了排序。最坏的情况发生在分割时产生出一个空的子区间——那完全没有达到分割的预期效果。

Qiuck Sort采用分段排序。分段的原则通常采用median-of-three(首、尾、中央的中间值)。任何一个元素都可以被当做枢轴,但是其合适与否会影响Quick Sort的效率。最理想最稳当的方式就是取整个序列的头、尾、中央三个位置的元素,以其中值作为枢轴。

以下是SGI STL提供的三点中值决定函数:

返回 a、b、c之居中者

template <class T>

inline const T& __median(cosnt T& a, const T& b, const T& c){

if(a<b)

if(b<c)

return b;

else if(a<c)

return c;

else

return a;

else if(a<c)

return a;

else if(b<c)

return c;

else

return b;

}

Partitioning(分割)

令头端迭代器first向尾部移动,尾端迭代器last向头部移动。当*first大于或等于枢轴时就停下来,当*last小于或等于枢轴时也停下来,然后检验两个迭代器是否交错。如果first仍然在左而last在右,就将两元素互换,然后两人各自调整一个位置(向中央逼近),再继续进行相同的行为。如果发现两个迭代器交错了,表示整个序列已经调整完毕,以此时的first为轴,将序列分为左右两半。

下面是SGI STL 提供的分割函数,其返回值是为分割后的右段第一个位置:

template <class RandomAccessItereator, class T>

RandomAccessIterator __unguarded_partition(RandomAccessIterator first,RandomAccessIterator last,T pivot){

while(true){

while(*first<pivot)++first;

--last;

while(*last>pivot)--last;

if(!(first<last))return first;

iter_swap(first,last);

++first;

}

}


原创粉丝点击