//arr[l...r]部分进行partition操作
//返回p,使得arr[l...p-1]<arr[p];arr[p+1...r]>arr[p]
template<typename T>
int _partition(T arr[], int l, int r) {
T v = arr[l];
//arr[l+1...j]<v;arr[j+1...i)>v
int j = l;
for (int i = l + 1; i <= r; i++) {
if (arr[i] < v) {
swap(arr[j + 1], arr[i]);
j++;
}
}
swap(arr[l], arr[j]);
return j;
}
//arr[l...r]部分进行快速排序
template<typename T>
void _quickSort(T arr[], int l, int r) {
if (l >= r)
return;
int p = _partition(arr, l, r);
_quickSort(arr, l, p - 1);
_quickSort(arr, p + 1, r);
}
template <typename T>
void quickSort(T arr[], int n) {
_quickSort(arr, 0, n - 1);
}
快排会出现不均衡的情况,如果有大量相同的值,就会出现左右分割的长度不均衡,为了改变这种情况。要将相同值得元素均匀的分散到不同的位置去。
template<typename T>
int _partition2(T arr[], int l, int r) {
T v = arr[l];
//arr[l+1...i)<=v;arr(j...r]>=v
int i = l + 1, j = r;
while (true) {
while (i <= r&&arr[i] < v) i++;
while (j >= l + 1 && arr[j] > v)j--;
if (i > j)break;
swap(arr[i], arr[j]);
i++;
j--;
}
swap(arr[l], arr[j]);
return j;
}
//arr[l...r]部分进行快速排序
template<typename T>
void _quickSort(T arr[], int l, int r) {
if (l >= r)
return;
int p = _partition2 (arr, l, r);
_quickSort(arr, l, p - 1);
_quickSort(arr, p + 1, r);
}
template <typename T>
void quickSort(T arr[], int n) {
_quickSort(arr, 0, n - 1);
}
对于有大量重复键值的数组进行排序时,可以选择三路快排
//三路快排处理arr[l...r]
//将arr[l...r]分为<v;==v;>v三部分
//之后递归对 < v;>v两部分进行三路快排
template<typename T>
void _quickSort3Ways(T arr[], int l, int r) {
//partition
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...i)==v
while (i < gt) {
if (arr[i] < v) {
swap(arr[i], arr[lt + 1]);
lt++;
i++;
}
else if (arr[i] > v) {
swap(arr[i], arr[gt - 1]);
gt--;
}
else
i++;
}
swap(arr[l], arr[lt]);
_quickSort3Ways(arr, l, lt - 1);
_quickSort3Ways(arr, gt, r);
}
template <typename T>
void quickSort3Ways(T arr[], int n) {
_quickSort3Ways(arr, 0, n - 1);
}