歸併排序
歸併排序是一種基於分治法的一種排序方法。它將要排序的序列分成兩個長度相等的子序列,爲每一個子序列進行排序,然後再將子序列合併成一個有序的序列。
比如對 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;
}