1.归并排序是什么?
归并排序(Merge Sort)是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
2.描述
归并排序算法的原理如下:
-
把长度为n的输入序列分成两个长度为n/2的子序列;;
-
对这两个子序列分别采用归并排序;
-
将两个排序好的子序列合并成一个最终的排序序列。
3.示例
递归版
// 归并排序
template <typename T>
inline void mergeSortRecursive(T arrs[], int length) {
if (length <= 1) return;
T *Arrs = new T[length]; // 存储归并数据
int mid = length >> 1;
// 将长为length的数据分为[0,n/2),[n/2, n)2个部分,分别进行归并
mergeSortRecursive(arrs, mid);
mergeSortRecursive(arrs + mid, length - mid);
//排序完成的2部分合并
int start1 = 0, end1 = mid, start2 = mid, end2 = length, k = 0;
while (start1 < end1 && start2 < end2)
Arrs[k++] = arrs[start1] < arrs[start2] ? arrs[start1++] : arrs[start2++];
while (start1 < end1) Arrs[k++] = arrs[start1++];
while (start2 < end2) Arrs[k++] = arrs[start2++];
memcpy(arrs, Arrs, length * sizeof(T));
if (Arrs != NULL) delete[] Arrs;
}
循环版
template <typename T>
inline void mergeSort(T arrs[], int length) {
T *Arrs = new T[length]; // 存储归并数据
int start1, end1, start2, end2, k;
for (int seq = 1; seq < length; seq = seq << 1) {
for (int start = 0; start < length; start += seq << 1) {
// 从2的幂(1,2,4,8,……)的大小对相邻的2组数据进行归并
int low = start;
int mid = MIN(start + seq, length);
int high = MIN(start + seq * 2, length);
k = low; // 归并起始点
start1 = low, end1 = mid; // 待归并数组[start1,end1)
start2 = mid, end2 = high; // 待归并数组[start2,end2)
while (start1 < end1 && start2 < end2)
Arrs[k++] =
arrs[start1] < arrs[start2] ? arrs[start1++] : arrs[start2++];
while (start1 < end1) Arrs[k++] = arrs[start1++];
while (start2 < end2) Arrs[k++] = arrs[start2++];
memcpy(arrs + low, Arrs + low, (high - low) * sizeof(T));
}
}
if (Arrs != NULL) delete[] Arrs;
}