#include<stdio.h>
#include<stdlib.h>
//此部分直接硬写出来的,没参考网上代码,写的可能拙劣一点
//非递归
void sort(int num[], int n) //接受待排序数组和数组长度
{
int tempnum = 1;
int *temp;
temp = (int*)malloc(n * sizeof(int)); //构建辅助数组,长度和待排序数组长度相同
int count; //用于每趟排序检测是否全部更新完
while (tempnum < n) //归并排序需要log(n)趟,tempnum每次自乘2,用于控制趟数
{
tempnum *= 2;
count = 0;
int countnum = n / tempnum;
if (n%tempnum != 0) //查看每趟有几个集合(划分),不能整除的话自增一
{
countnum += 1;
}
int m = 1;
for (int i = 0, j = i + tempnum / 2; count < n; i += tempnum / 2, j += tempnum / 2)
{
while (i < ((2 * m - 1)*tempnum / 2) && j < m*tempnum&&i < n&&j < n)
{
if (num[i] < num[j])
{
temp[count] = num[i]; //可直接写成temp[count++]=num[i++],下面同理
i++;
}
else
{
temp[count] = num[j];
j++;
}
count++;
}
if (i < ((2 * m - 1)*tempnum / 2) && i < n)
//如果有一个点标没到达指定位置,则把这个数组的剩余部分复制到辅助数组,else if()同理
{
for (; i < ((2 * m - 1)*tempnum / 2); ++i)
{
temp[count] = num[i];
count++;
}
}
else if (j < m*tempnum&&j < n)
{
for (; j < m*tempnum&&j < n; ++j)
{
temp[count] = num[j];
count++;
}
}
m++;
}
for (int i = 0; i < n; ++i) //每趟排序完借助辅助数组更新待排序数组的值
//此部分可在上面更新temp[]值的同时对num[]进行更新,而不必另外加一个for循环
{
num[i] = temp[i];
//printf("%d ", num[i]);
}
//printf("\n");
}
free(temp);
}
//递归部分和网上大多数思路相同,此部分沿用下面博客的递归实现代码
//https://www.cnblogs.com/bluestorm/archive/2012/09/06/2673138.html
//递归
void merge(int num[], int start, int mid, int end)
{
int n1 = mid - start + 1;
int n2 = end - mid;
int *left, *right;
left = (int*)malloc(n1 * sizeof(int));
right = (int*)malloc(n2 * sizeof(int));
int i, j, k;
for (i = 0; i < n1; i++)
left[i] = num[start + i];
for (j = 0; j < n2; j++)
right[j] = num[mid + 1 + j];
i = j = 0;
k = start;
while (i < n1 && j < n2)
if (left[i] < right[j])
num[k++] = left[i++];
else
num[k++] = right[j++];
while (i < n1)
num[k++] = left[i++];
while (j < n2)
num[k++] = right[j++];
free(left);
free(right);
}
void merge_sort(int num[], int start, int end)
{
int mid;
if (start < end)
{
mid = (start + end) / 2;
merge_sort(num, start, mid);
merge_sort(num, mid + 1, end);
merge(num, start, mid, end);
}
}
int main()
{
printf("---------非递归---------\n");
int num[7] = { 49,38,65,97,76,13,27 };
int n = 7;
sort(num, n);
for (int i = 0; i < n; ++i)
{
printf("%d ", num[i]);
}
printf("\n");
printf("---------递归---------\n");
int num2[7] = { 49,38,65,97,76,13,27 };
merge_sort(num2, 0, 6);
for (int i = 0; i < n; ++i)
{
printf("%d ", num2[i]);
}
return 0;
}
对非递归的函数的代码简化版:
#include<stdio.h>
#include<stdlib.h>
//非递归
void sort(int num[], int n)
{
int tempnum = 1;
int *temp;
temp = (int*)malloc(n * sizeof(int));
int count;
while (tempnum < n)
{
tempnum *= 2;
count = 0;
int countnum = n / tempnum;
if (n%tempnum != 0)
countnum += 1;
int m = 1;
for (int i = 0, j = i + tempnum / 2; count < n; i += tempnum / 2, j += tempnum / 2)
{
for (int x = 0; x < n; ++x)
{
printf("%d ", num[x]);
}
printf("\n");
while (i < ((2 * m - 1)*tempnum / 2) && j < m*tempnum&&i < n&&j < n)
{
if (num[i] < num[j])
temp[count++] = num[i++];
else
temp[count++] = num[j++];
}
if (i < ((2 * m - 1)*tempnum / 2) && i < n)
{
while (i < ((2 * m - 1)*tempnum / 2))
temp[count++] = num[i++];
}
else if (j < m*tempnum&&j < n)
{
while (j < m*tempnum&&j < n)
temp[count++] = num[j++];
}
m++;
}
for (int i = 0; i < n; ++i)
{
num[i] = temp[i];
printf("%d ", num[i]);
}
printf("\n");
}
free(temp);
}
int main()
{
int num[7] = { 49,38,65,97,76,13,27 };
int n = 7;
sort(num, n);
for (int i = 0; i < n; ++i)
{
printf("%d ", num[i]);
}
printf("\n");
return 0;
}
可以看一下参考部分的博客,原作者的非递归算法实现的很简洁(虽然我还没有看)
参考:
https://www.cnblogs.com/bluestorm/archive/2012/09/06/2673138.html