基本思想:
归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为,称为二路归并。
核心思想:
将两个已经排好序的数组,合成一个排好序的数组
如果:一个数组只有一个元素,那么这个数组一定是有序的
问题:
- 我们该如何把一个乱序的数组,分为全是只有一个元素的数组?(答案:递归)
- 我们又该如何把多个只有一个元素的数组合并成一个有序的数组?
代码演示:
cpp
void MergeSort(int* a, int n)
{
int* tmp = (int*)malloc(sizeof(int) * n);
if (tmp == NULL)
{
perror("malloc::fail");
return;
}
_MergeSort(a, 0, n - 1, tmp);
}
void _MergeSort(int* a, int begin, int end, int* tmp)
{
if(begin>=end)//当只有一个元素排序时候就停止了,毕竟数组只有一个元素就相当于排好序了
return;
int mid = (begin + end) / 2;
_MergeSort(a, begin, mid, tmp);//递归的目的是把数组打散
_MergeSort(a, mid+1, end, tmp);
int begin1 = begin, end1 = mid;//将两个排好序的数组,变成一个排序序的数组
int begin2 = mid + 1, end2 = end;
int i = begin;
while (begin1 <= end1 && begin2 <= end2)
{
if (a[begin1] < a[begin2])
{
tmp[i++] = a[begin1++];
}
else
{
tmp[i++] = a[begin2];
}
}
while (begin1 <= end1)//当其中的一个数组走完,但另一个数组没走完,就把剩下的数组的数据插入就行
{
tmp[i++] = a[begin1++];
}
while (begin2 <= end2)
{
tmp[i++] = a[begin2++];
}
memcpy(a + begin, tmp + begin, sizeof(int) * (end - begin - 1));
}
归并排序的特性总结:
- 归并的缺点在于需要O(N)的空间复杂度,归并排序的思想更多的是解决再磁盘中的外排序问题
- 时间复杂度:O(NlogN)
- 空间复杂度:O(N)
- 稳定性:稳定