C++数据结构与算法之:高级排序算法
大家好,我是奋斗的C菌,今天和大家分享我对高级排序算法的理解以及历代优化代码,大家加油加油加油加油加油加油加油加油加油!!!
归并排序(MergeSort):
//第一次算法:平均时间复杂度O(nlogn),但在近乎有序数组排序时效果没有insertionSort好
template<typename T>
void mergeSort(T arr[], int n) {
__mergeSort(arr, 0, n - 1);
}
template<typename T>
void __mergeSort(T arr[],int L,int R){//把arr[]不断的分成若干个小区间,执行__merge递归
if(L>=R)
return;
int mid = (L+R)/2;
__mergeSort(arr,L,mid);
__mergeSort(arr,R,mid);
__merge(arr,L,mid,r);
}
template<typename T>
void __merge(T arr[],int L,int mid,int R){//开辟一个arr[]的副本TempArr[],副本分为俩部分,TempArr[左值L,中间值mid);TempArr[中间值mid,右值R)
T *TempArr = new T[R-L+1];
for(int i = L;L<=R;i++)
TempArr[i-L] = arr[i];
int i = L,j=mid+1;
for(int k = L;k<R;k++){//左边部分的第一个值和右边部分第一个值比较,大的赋值给arr[k],大的那边迭代+1,小的那边不变,注意边界检查
if (i > mid) {
arr[k] = TempArr[j - L];
j++;
}
else if (j > R) {
arr[k] =TempArr[i - L];
i++;
}
else if(TempArr[i-L]<TempArr[j-L]){
arr[k]=TempArr[i-L];
i++;
}else{
arr[k]=TempArr[j-L];
j++;
}
}
}
/优化,在左右边界15范围内,使用插入排序
template<typename T>
void __mergeSort(T arr[], int l, int r) {
if (r - l <= 15) {
insertionSort(arr, l, r);
return;
}
int mid = (l + r) / 2;
__mergeSort(arr, l, mid);
__mergeSort(arr, r, mid);
if (arr[mid] > arr[mid + 1])//小优化,如果左边的最大值小于右边的最小值,可以少一次递归。
__merge(arr, l, mid, r);
}
自底向上的归并排序:
//自底向上归并,效果和普通归并差不多
template<typename T>
void mergeSortBU(T arr[], int n) {
for (int size = 1; size < n; size += size)
{
for (int i = 0; i + size < n; i += size + size) {
__merge(arr, i, i + size - 1, min(i + size + size - 1, n - 1));
}
}
}
快速排序(QuickSort):
template<typename T>
template<typename T>
void quickSort(T arr[], int n) {
srand(time(NULL));
__quickSort(arr, 0, n - 1);
}
//对arr[L,R]部分进行快速排序
template<typename T>
void __quickSort(T arr[], int L, int R) {
if (R - L <= 15) {
insertionSort(arr, L, R);
return;
}
int p = __partition(arr, L, R);
__quickSort(arr, L, p - 1);
__quickSort(arr, p + 1, R);
}
template<typename T>
int __partition(T arr[], int L, int R) {
swap(arr[L], arr[rand() % (R - L + 1) + L]);
T v = arr[L];
//arr[L+1,J]<v,arr[j+1,R)>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;
}
双路快速排序:
template<typename T>
int __partition2Ways(T arr[], int L, int R) {
swap(arr[L], arr[rand() % (R - L + 1) + L]);
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;
}
template<typename T>
void __quickSort2Ways(T arr[], int L, int R) {
if (R - L <= 15) {
insertionSort(arr, L, R);
return;
}
int p = __partition2(arr, L, R);
__quickSort2Ways(arr, L, p - 1);
__quickSort2Ways(arr, p + 1, R);
}
template<typename T>
void quickSort2Ways(T arr[], int n) {
srand(time(NULL));
__quickSort2Ways(arr, 0, n - 1);
}
三路快速排序:
//将arr[L,R]分为<V,==V;>V,三部分
//之后递归对<V;>V两部分进行三路快速排序
template<typename T>
void __quickSort3Ways(T arr[], int L, int R) {
if (R - L <= 15) {
insertionSort(arr, L, R);
return;
}
//partition
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,i]==V
while (i < Gt) {
if (arr[i] < v) {//arr[L+1,lt]<V
swap(arr[i], arr[Lt + 1]);
i++; Lt++;
}
else if (arr[i] > v) {//arr[Gt,R]>V
swap(arr[i], arr[Gt - 1]);
Gt--;
}
else {//arr[L+1,lt]<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);
}