test.1 递归
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
void MergeSort(int* array, int begin, int end)
{
if (begin >= end)
return;
//相当于二叉树后序
int mid = (end-begin) / 2 + begin;
MergeSort(array, begin, mid);
MergeSort(array, mid+1, end);
//归并开始
int size = end - begin + 1;
int* midarray = (int*)malloc(sizeof(int) * size);
assert(midarray);
int pcura = begin;
int pcurb = mid+1;
int i = 0;
while (pcura <= mid && pcurb <= end)
{//升序
if (array[pcura] < array[pcurb])
{
midarray[i] = array[pcura];
pcura++;
}
else
{
midarray[i] = array[pcurb];
pcurb++;
}
i++;
}
while (pcura <= mid)
{
midarray[i++] = array[pcura++];
}
while (pcurb <= end)
{
midarray[i++] = array[pcurb++];
}
memcpy(array + begin, midarray, size*sizeof(int));
//不能直接sizeof(midarray),midarray是指针,它指向一块动态开辟的空间
free(midarray);
}
int main()
{
int array[10] = { 2,13,4,24,5,45,642,31,1,3 };
MergeSort(array, 0, 9);
for (int i = 0; i < 10; i++)
printf("%d ", array[i]);
return 0;
}
test.2 非递归
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#include<time.h>
//递归改非递归一般可以用栈和循环,栈对于前序遍历比较方便,入一个出一个入几个,后序入两边不好入
void MergeSort(int begin, int end, int* array)
{
int n = end - begin + 1;
int* arry = (int*)malloc(sizeof(int) * n);//中间数组
assert(arry);
//控制每组内两数组间距
for (int gap = 1; gap < n; gap *= 2)//每次排完两组合并,组距翻倍
{
//控制多少组
for (int i = begin; i < n; i += 2 * gap)
{
int start1 = i;
int end1 = i + gap - 1;
int start2 = i + gap;
int end2 = i + 2 * gap - 1;
if (end1 >= n || start2 >= n)
break;
if (end2 >= n)//第二组数超过末尾,改为末尾,让结尾数也能排到
end2 = n - 1;
//开始排序
int cur1 = start1;
int cur2 = start2;
int cur_arr = start1;
//现在排升序
while (cur1 <= end1 && cur2 <= end2)
{
if (array[cur1] < array[cur2])
arry[cur_arr++] = array[cur1++];
else
arry[cur_arr++] = array[cur2++];
}
while(cur1<=end1)
arry[cur_arr++] = array[cur1++];
while(cur2<=end2)
arry[cur_arr++] = array[cur2++];
memcpy(array + start1, arry + start1, (end2 - start1 + 1) * sizeof(int));
}
}
free(arry);
}
int main()
{
srand((unsigned int)time(0));
#define NUM 1000
int a[NUM];
for (int i = 0; i < NUM; i++)
a[i] = rand() % 1000 + 1;
MergeSort(0, NUM-1, a);
for (int i = 0; i < NUM; i++)
{
printf("%d\n", a[i]);
assert(i==0?1:a[i] >= a[i - 1]);//检查每个后面的比前面的大
}
return 0;
}