环境:Visual Studio 2019
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int min(int a, int b)
{
if (a < b)
return a;
else
return b;
}
void func(int arr[], int length)
{
if (length < 2)
return;//小于两个元素不需要排序。
int* a = arr;//a指向待排序的数组。
int* b = (int*)malloc(length * sizeof(int));//b指向已排序的数组。
int part = 0;//part:区间分段的计数器,1,2,4,8,16……
int start = 0;//区间起始位置的计数器。
//排序的趟数的循环。
for (part = 1; part < length; part = part * 2)
{
//每趟排序选取区间的循环。
for (start = 0; start < length; start = start + part * 2)
{
//把每个区间分成两部分,left是起始位置,mid是中间位置,right是结束位置。
int left = start;
int mid = min(start + part, length);//考虑分段不均的情况,mid不能超出length。
int right = min(start + part * 2, length);//考虑分段不均的情况,right也不能超出length。
int i = left;//已排序数组的计数器。
int start1 = left, end1 = mid;//待排序左边数列的起始和结束位置。
int start2 = mid, end2 = right;//待排序右边数列的起始和结束位置。
//把待排序左右两边数列合并到已排序数组。
while ((start1 < end1) && (start2 < end2))
b[i++] = a[start1] < a[start2] ? a[start1++] : a[start2++];
//把左边数列其它的元素追加到已排序数组。
while (start1 < end1)
b[i++] = a[start1++];
//把右边数列其它的元素追加到已排序数组。
while (start2 < end2)
b[i++] = a[start2++];
}
//交换一下两个数组的指针,准备下一躺排序。
int* p = a;
a = b;
b = p;
}
//如果a指向的不是原始数组的指针,把a中的内存复制到arr中。
if (a != arr)
{
memcpy(arr, a, length * sizeof(int));
b = a;
}
free(b);
}
int main()
{
int a[100];
int len = 0;
scanf_s("%d", &len);
for (int i = 0; i < len; i++)
{
scanf_s("%d", &a[i]);
}
func(a, len);
for (int j = 0; j < len; j++)
{
printf("%d", a[j]);
if (j <= len - 1)
printf(" ");
}
printf("\n");
return 0;
}