归并排序
#include <iostream>
using namespace std;
// 将arr[l...mid]和arr[mid+1...r]两部分进行归并
template<typename T>
void __merge(T arr[], int l, int mid, int r) {
//* 使用new申请空间, 不要忘了delete掉申请的空间:)
T *aux = new T[r-l+1];
for (int i = l; i <= r; i++)
aux[i - l] = arr[i];
// 初始化,i指向左半部分的起始索引位置l;j指向右半部分起始索引位置mid+1
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++;
}
}
delete[] aux;
}
// 递归使用归并排序,对arr[l...r]的范围进行排序
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);
}
优化的归并排序
适用于近乎有序的数组,并且小规模部分采用插入排序。
#include <iostream>
#include <algorithm>
#include "InsertionSort.h"
using namespace std;
// 将arr[l...mid]和arr[mid+1...r]两部分进行归并
template<typename T>
void __merge(T arr[], int l, int mid, int r) {
T *aux = new T[r-l+1];
for (int i = l; i <= r; i++)
aux[i - l] = arr[i];
// 初始化,i指向左半部分的起始索引位置l;j指向右半部分起始索引位置mid+1
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++;
}
}
//delete[] aux;
}
// 使用优化的归并排序算法, 对arr[l...r]的范围进行排序
template<typename T>
void __mergeSort(T arr[], int l, int r) {
/*
*对于小规模数组, 使用插入排序
*因为数据规模小时,插排的效率更高
*/
if (r - l <= 15) {
for (int i = l + 1; i <= r; i++) {
T e = arr[i];
int j;
for (j = i; j > l&& arr[j - 1] > e; j--)
arr[j] = arr[j - 1];
arr[j] = e;
}
return;
}
int mid = (l + r) / 2;
__mergeSort(arr, l, mid);
__mergeSort(arr, mid + 1, r);
/*
*对于arr[mid] <= arr[mid+1]的情况,不进行merge
*对于近乎有序的数组非常有效,但是对于一般情况,有一定的性能损失
*/
if (arr[mid] > arr[mid + 1])
__merge(arr, l, mid, r);
}
template<typename T>
void mergeSort(T arr[], int n) {
__mergeSort(arr, 0, n - 1);
}