#include <stdio.h>
#include <stdlib.h>
#include<assert.h>
#include<time.h>
void Show(int *arr,int len)
{
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
归并排序的基本思想:
拆分成多个组合 最后拆分成两两比较的 然后组内排序 最后合并有序数组
void Merge(int *arr, int len, int wide)//wide就是几个数字一合并
{
int L1 = 0;
int H1 = L1 + wide - 1;
int L2 = H1 + 1;
int H2 = (L2 + wide - 1) <= (len - 1) ? (L2 + wide - 1) : (len - 1);
int *crr = (int *)malloc(sizeof(int)*len);
assert(crr != NULL);
int i = 0;
while (L2 <= len - 1)
{
while (L1 <= H1 && L2 <= H2)
{
if (arr[L1] < arr[L2])
{
crr[i++] = arr[L1++];
}
else
{
crr[i++] = arr[L2++];
}
}
while (L1 <= H1)
{
crr[i++] = arr[L1++];
}
while (L2 <= H2)
{
crr[i++] = arr[L2++];
}
L1 = H2 + 1;
H1 = L1 + wide - 1;
L2 = H1 + 1;
H2 = (L2 + wide - 1) <= (len - 1) ? (L2 + wide - 1) : (len - 1);
}
while (L1 <= len - 1)
{
crr[i++] = arr[L1++];
}
for (int i = 0; i < len; i++)//将值赋给arr,释放申请的空间crr
{
arr[i] = crr[i];
}
free(crr);
}
void MergeSort(int *arr,int len)
{
if (arr == NULL) return;
for (int i = 1; i < len; i = i * 2)
{
Merge(arr,len,i);
}
}
int main()
{
int arr1[] = {11,3,15,10,7,2,44,1,0};
int n1 = sizeof(arr1) / sizeof(sizeof(arr1[0]));
//归并排序 空间复杂度n 时间复杂度 2n*logn 稳定
printf("归并排序(递归):\n");
MergeSort(arr1,n1);
Show(arr1, n1);
return 0;
}
运行结果:
归并排序 空间复杂度n 时间复杂度 2n*logn 稳定
归并排序和堆排序、快速排序的比较
若从空间复杂度来考虑:首选堆排序,其次是快速排序,最后是归并排序。
若从稳定性来考虑,应选取归并排序,因为堆排序和快速排序都是不稳定的。
若从平均情况下的排序速度考虑,应该选择快速排序。