三路快速排序算法分析
双路快速排序算法把等于v的数据分为两部分,方式了数据量一边倒的情况,三路排序算法把排序的数据分为三部分,分别为小于v,等于v,大于v,这样三部分的数据中,等于v的数据在下次递归中不再需要排序,小于v和大于v的数据也不会出现某一个特别多的情况(如下图所示),通过此方式三路快速排序算法的性能更优。
三路快速排序主要关注三个标志,分别为lt,i,gt,这三个标志会把数据分为四部分,arr[l+1...lt]的数据全部小于v,arr[lt+1...i-1]的数据等于v,arr[i...gt-1]的为待排序的数据,arr[gt...r]的数据大于v,具体的代码实现如下:
template<typename T> void _quickSort3Ways(T arr[], int l, int r) { //小规模数据使用插入排序 if(r-l <= 15) { insertionSort(arr, l, r); return; } // 随机在arr[l...r]的范围中, 选择一个数值作为标定点pivot swap( arr[l], arr[rand()%(r-l+1)+l ] ); T v = arr[l]; int lt = l; //arr[l+1...lt] < v int gt = r+1; //arr[gt...r] > v int i = l+1; //arr[lt+1...gt-1] == v while(i < gt) { if(arr[i] < v) { swap(arr[i], arr[lt+1]); i++; lt++; } else if(arr[i] > v) { swap(arr[i], arr[gt-1]); gt--; } else //arr[i] == v i++; } swap(arr[l], arr[lt]); _quickSort3Ways(arr, l, lt-1); _quickSort3Ways(arr, gt, r); } template<typename T> void quickSort3Ways(T arr[], int n) { srand(time(NULL)); _quickSort3Ways(arr, 0, n-1); }
三路快速排序算法对具有大量重复的数据排序性能很好。
排序算法性能对比
下边对比相同数据量下,几乎有序的数据、大量重复的数据情况下,归并排序、希尔排序、不同快速排序、双路快速排序、三路快速排序的性能:
通过初步对比百万数据量的排序得出以下几点结论:
1、随机的百万数据量排序中,快速排序算法性能相对较好。
2、对于百万几乎有序的数据量(不存在重复数据) ,希尔排序和归并排序性能最好,快速排序性能也不差。
3、对于百万具有大量重复数据的情况,之前未优化过的普通快速排序性能很差,三路快速排序算法性能最好。
以上是粗略测试,不同的数据可能具体结果会有差异,但是如果通过大量数据进行多轮测试,快速排序算法性能会最优,毕竟快速排序算法的时间复杂度为O(nlog(n))。