归并排序
归并排序是一种基于分治法的一种排序方法。它将要排序的序列分成两个长度相等的子序列,为每一个子序列进行排序,然后再将子序列合并成一个有序的序列。
比如对 10 4 6 3 8 2 5 7 这个数列排序
代码:
template<class T>
void _Merge(T* arr, T* tmp, int begin, int end)
{
int mid = ((begin ^ end) >> 1) + (begin & end);
if (mid > begin)
_Merge(arr, tmp, begin, mid);
if (mid + 1 < end)
_Merge(arr, tmp, mid + 1, end);
int index = begin;
int begin1 = begin;
int end1 = mid;
int begin2 = mid + 1;
int end2 = end;
while (begin1 <= end1 && begin2 <= end2){
if (arr[begin1] < arr[begin2]){
tmp[index++] = arr[begin1++];
}
else{
tmp[index++] = arr[begin2++];
}
}
while (begin1 <= end1){
tmp[index++] = arr[begin1++];
}
while (begin2 <= end2){
tmp[index++] = arr[begin2++];
}
while (begin <= end){
arr[begin] = tmp[begin++];
}
}
template<class T>
void MergeSort(T* arr, size_t n)
{
assert(arr);
int begin = 0;
int end = n - 1;
T* tmp = new T[n];
_Merge(arr, tmp, begin, end);
delete[] tmp;
}
为了防止递归函数栈帧开销 所以将元素数量小于13的小段待排序列用直接插入排序解决。
代码:
template<class T>
void _Merge(T* arr, T* tmp, int begin, int end)
{
int mid = ((begin ^ end) >> 1) + (begin & end);
if (mid > begin){
if (mid - begin + 1 > 13){
_Merge(arr, tmp, begin, mid);
}
else{
InsertSort(arr + begin, mid - begin + 1);
}
}
if (mid + 1 < end){
if (end - mid > 13){
_Merge(arr, tmp, mid + 1, end);
}
else{
InsertSort(arr + mid + 1, end - mid);
}
}
int index = begin;
int begin1 = begin;
int end1 = mid;
int begin2 = mid + 1;
int end2 = end;
while (begin1 <= end1 && begin2 <= end2){
if (arr[begin1] < arr[begin2]){
tmp[index++] = arr[begin1++];
}
else{
tmp[index++] = arr[begin2++];
}
}
while (begin1 <= end1){
tmp[index++] = arr[begin1++];
}
while (begin2 <= end2){
tmp[index++] = arr[begin2++];
}
while (begin <= end){
arr[begin] = tmp[begin++];
}
}
template<class T>
void MergeSort(T* arr, size_t n)
{
assert(arr);
int begin = 0;
int end = n - 1;
T* tmp = new T[n];
_Merge(arr, tmp, begin, end);
delete[] tmp;
}