参考博客
简要介绍
建立在归并操作上的一种稳定的排序算法,采用分治策略,时间复杂度O(n log n),空间复杂度T(n)。
基本思想
先使每个子序列有序,再使子序列段间有序,将已有序的子序列合并,得到完全有序的序列。
实现思路
先递归分解数列,再合并数列完成归并。
递归分解操作:将整个元素分为两组,再将每组分为两组,以此类推,直到分出来的小组只有一个数据时,认为小组组内有序,合并相邻的两个小组。归并操作:申请空间,设置两个指针,最初位置分别为两个已将排过序序列的起始位置,比较两个指针指向的元素,选择相对小的元素放入新申请的空间,并将该元素的指针往后移一位,重复直到某一指针超出序列,将剩下序列所有元素直接合并到序列尾。
代码实现
void mergearr(int arr[], int left, int mid, int right, int tmp[]){
int l = left;
int tmpdex = 0;
int rstar = mid + 1;
while (l <= mid && rstar <= right){ //判断越界条件
if (arr[l] <= arr[rstar]){
tmp[tmpdex] = arr[l];
l++;
}
else{
tmp[tmpdex] = arr[rstar];
rstar++;
}
tmpdex++;
}
while (l <= mid){
tmp[tmpdex] = arr[l];
tmpdex++;
l++;
}
while (rstar <= right){
tmp[tmpdex] = arr[rstar];
tmpdex++;
rstar++;
}
for (int i = 0; i < tmpdex; ++i) //left+i到tmpdex-1区间内有序
arr[left + i] = tmp[i];
}
void mergesort(int arr[], int left, int right, int tmp[]){
if (left < right){
int mid = (left + right) / 2;
mergesort(arr, left, mid, tmp); //左边有序
mergesort(arr, mid + 1, right, tmp); //右边有序
mergearr(arr, left, mid, right, tmp); //归并
}
}
void MergeSort(int arr[], int size){
int* p = new int[size]; //存放合并后的元素
mergesort(arr, 0, size - 1, p); //分组
delete[] p;
p = nullptr;
}