Skip to content

Commit 07483e7

Browse files
committed
Merge pull request xtaci#22 from solome/patch-1
快速排序:枢纽值「pivot」选取进行优化
2 parents 2a4d5d3 + d549039 commit 07483e7

File tree

1 file changed

+36
-15
lines changed

1 file changed

+36
-15
lines changed

include/quick_sort.h

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,42 +19,63 @@
1919
#define __QUICKSORT_H__
2020

2121
#include <generic.h>
22+
#include <cassert>
2223

2324
namespace alg {
25+
26+
/**
27+
* Return median of begin, middle, and end.
28+
* Order these and hide the pivot.
29+
*/
30+
template<typename T>
31+
static const T & __median3(T list[], int begin, int end) {
32+
assert(begin + 2 <= end);
33+
int middle = end - (end - begin) / 2;
34+
if (list[middle] < list[begin])
35+
swap(list[middle], list[begin]);
36+
if (list[end] < list[begin])
37+
swap(list[end], list[begin]);
38+
if (list[end] < list[middle])
39+
swap(list[end], list[middle]);
40+
41+
//Place pivot at position [end - 1]
42+
swap(list[middle], list[end - 1]);
43+
return list[end - 1];
44+
}
45+
2446
/**
2547
* the quick-sort partition routine
2648
*/
2749
template<typename T>
2850
static int __partition(T list[],int begin, int end) {
29-
int pivot_idx = RANDOM(begin,end);
30-
T pivot = list[pivot_idx];
31-
swap(list[begin], list[pivot_idx]);
32-
33-
int i = begin + 1;
34-
int j = end;
35-
36-
while(i <= j) {
37-
while((i <= end) && (list[i] <= pivot))
38-
i++;
39-
while((j >= begin) && (list[j] > pivot))
40-
j--;
51+
T pivot = __median3<T>(list, begin, end);
52+
53+
int i = begin;
54+
int j = end - 1;
55+
56+
while(i < j) {
57+
while(list[++i] < pivot) {}
58+
while(pivot < list[--j]) {}
4159
if(i < j)
4260
swap(list[i],list[j]);
4361
}
4462

45-
swap(list[begin],list[j]);
46-
return j; // final pivot position
63+
swap(list[i],list[end - 1]);
64+
return i; // final pivot position
4765
}
4866

4967
/**
5068
* quick sort an array of range [begin, end]
5169
*/
5270
template<typename T>
5371
static void quicksort(T list[],int begin,int end) {
54-
if( begin < end) {
72+
if( begin + 1 < end) {
5573
int pivot_idx = __partition<T>(list, begin, end);
5674
quicksort(list, begin, pivot_idx-1);
5775
quicksort(list, pivot_idx+1, end);
76+
} else if ( begin + 1 == end) {
77+
if (list[begin + 1] > list[end])
78+
swap(list[begin + 1], list[end]);
5879
}
5980
}
6081
}

0 commit comments

Comments
 (0)