归并排序也是常用的排序之一,归并,你可以将它拆开理解就懂这个词的意思了;
直接上我画的草稿:
![](https://i-blog.csdnimg.cn/blog_migrate/d266af0bd2aac7018ad3af95a08feb3c.png)
![](https://i-blog.csdnimg.cn/blog_migrate/da3108cf1c4302a9171dca1a2587db26.png)
![](https://i-blog.csdnimg.cn/blog_migrate/6d4d9dfc0cc5f19d8bdf8c6875f1803a.png)
void _MergeSort1(int*a, int begin, int end, int*temp)
{
if (begin >= end)
return;
int mid = (begin + end) / 2;
//分解
_MergeSort1(a, begin, mid, temp);
_MergeSort1(a, mid+1, end, temp);
//归并
int begin1 = begin, end1 = mid;
int begin2 = mid + 1, end2 = end;
int i = begin;
while (begin1 <= end1 && begin2 <= end2)
{
if (a[begin1] <= a[begin2])
{
temp[i++] = a[begin1++];
}
else
{
temp[i++] = a[begin2++];
}
}
//可能出现一个组里有数据另一个分组里没有数据,这时跳出上面的循环,需要再拷贝一次
while (begin1 <= end1)
{
temp[i++] = a[begin1++];
}
while (begin2 <= end2)
{
temp[i++] = a[begin2++];
}
memcpy(a, temp, sizeof(int) * (end-begin+1));
}
二、归并排序的非递归方法:
如果我们想用非递归去写,我们就要先了解她的递归方式;
归并排序的递归是将数据分解,然后将不可再分的数据进行排序后,放入创建的数组中,最后再拷贝回原数组。非递归我们要设置一个rangN,来控制比较的数据组数。
![](https://i-blog.csdnimg.cn/blog_migrate/2c1eea77d913486df21c3a84775ad52f.png)
二、大概的过程就是这样,但是其中还有一些BUG。
当rangN不是2的次方倍时,就可能出现数组越界的情况
![](https://i-blog.csdnimg.cn/blog_migrate/9a151a11706db14869e24a0938c06a9c.png)
以下是我写的代码
void _MergeSort2(int* a, int n)
{
int* temp = (int*)malloc(sizeof(int) * n);
if (temp == NULL)
{
perror("malloc error");
exit(-1);
}
//归并
int rangN = 1;
while (rangN < n)
{
for (int i = 0; i < n; i += 2 * rangN )
{
int begin1 = i, end1 = i + rangN - 1;
int begin2 = i + rangN, end2 = i + 2 * rangN - 1;
int j = i;
//修正越界的情况
if (end1 >= n)
{
end1 = n - 1;
begin2 = n;
end2 = n - 1;
}
else if (begin2 >= n)
{
begin2 = n;
end2 = n - 1;
}
else if (end2 >= n)
{
end2 = n - 1;
}
printf("[%d,%d],[%d,%d]\n", begin1, end1, begin2, end2);
while (begin1 <= end1 && begin2 <= end2)
{
if (a[begin1] <= a[begin2])
{
temp[j++] = a[begin1++];
}
else
{
temp[j++] = a[begin2++];
}
}
while (begin1 <= end1)
{
temp[j++] = a[begin1++];
}
while (begin2 <= end2)
{
temp[j++] = a[begin2++];
}
}
memcpy(a, temp, sizeof(int) * (n));
rangN *= 2;
}
}
今天的归并排序就到这里。