版权声明:本文未经允许不得转载 https://blog.csdn.net/weixin_43873349/article/details/87709004
O(nlogn)排序算法(C++)
归并排序
首先进行分解成两部分,之后递归分解,分解到每个单元只有一个数据元素时,不用排序,逐层归并。
template <typename T>
void __merge(T arr[], int l, int mid, int r){
T aux[r-l+1];
for(int i = l; i <= r; i++){
aux[i-l] = arr[i];
}
int i = l, j = mid + 1;
for(int k = l; k <= r; k++){
if(i > mid){
arr[k] = aux[j-l];
j++;
}else if(j > r){
arr[k] = aux[i-l];
i++;
}else if(aux[i-l] < aux[j-l]){
arr[k] = aux[i-l];
i++;
}else{
arr[k] = aux[j-l];
j++;
}
}
}
template <typename T>
void __mergeSort(T arr[], int l, int r){
if(l >= r){
return;
}
int mid = (l + r) / 2;
__mergeSort(arr, l, mid);
__mergeSort(arr, mid+1, r);
__merge(arr, l, mid, r);
}
template <typename T>
void mergeSort(T arr[], int n){
__mergeSort(arr, 0, n-1);
}
归并排序的改进一
当遇到近乎有序的待排序序列时,上面的归并排序算法就不如改进式的插入排序算法,因为改进式插入排序算法可以分解到O(n)的时间复杂度,而归并排序本身还是会分解log(n)层级。所以做出改进一,之前是递归排序后,无论如何,直接将两个子序列进行归并,改进为:当前一个序列的最后一个元素比后一个序列的第一个元素还要大时,在进行归并。因为两个子序列都已经有序。
template <typename T>
void __mergeSort(T arr[], int l, int r){
if(l >= r){
return;
}
int mid = (l + r) / 2;
__mergeSort(arr, l, mid);
__mergeSort(arr, mid+1, r);
if(arr[mid] > arr[mid+1]){
__merge(arr, l , mid, r);
}
}
归并排序的改进二
由于时间复杂度的缘故,当待排序列数量足够小的时候,改进式插入排序算法效率优于归并排序算法,所以在递归终止条件上进行改进。即在正常的归并排序基础上,当待排序列数量在一定小的数量范围之内用改进式插入排序。
template <typename T>
void insertionSort2(T arr[], int l, int r){
for(int i = l+1; i <= r; i++){
T e = arr[i];
int j;
for(j = i; j > l; j--){
if(arr[j-1] > e){
arr[j] = arr[j-1];
}else{
break;
}
}
arr[j] = e;
}
}
template <typename T>
void __mergeSort(T arr[], int l, int r){
/*if(l >= r){
return;
}*/
if(r-l <= 15){
insertionSort2(arr, l, r);
return;
}
int mid = (l + r) / 2;
__mergeSort(arr, l, mid);
__mergeSort(arr, mid+1, r);
if(arr[mid] > arr[mid+1]){
__merge(arr, l , mid, r);
}
}