递归版本
//归并排序:递归版
void _MergeSort(int* a, int left, int right,int* tmp)
{
if (left == right)
return;
int mid = (left + right) / 2;
//分解
//[begin, mid] [mid+1,end]
_MergeSort(a, left, mid,tmp);
_MergeSort(a, mid+1,right,tmp);
//归并
int begin1 = left, end1 = mid;
int begin2 = mid + 1, end2 = right;
int i = left;
//两组有序数组,数字小的进行尾插
while (begin1 <= end1 && begin2 <= end2)
{
if (a[begin1] <= a[begin2])
{
tmp[i++] = a[begin1++];
}
else
{
tmp[i++] = a[begin2++];
}
}
while (begin1 <= end1)
{
tmp[i++] = a[begin1++];
}
while (begin2 <= end2)
{
tmp[i++] = a[begin2++];
}
//left不一定是从0开始,所以拷贝时,注意拷贝位置
memcpy(a + left, tmp + left, sizeof(int) * (right-left + 1));
}
void MergeSort(int* a, int n)
{
int* tmp = (int*)malloc(sizeof(int) * n);
if (tmp == NULL)
{
perror("malloc fail");
return;
}
_MergeSort(a,0, n-1,tmp);
}
非递归版
//非递归
void MergeNonR(int* a, int left, int right, int n)
{
int* tmp = (int*)malloc(sizeof(int) * n);
if (tmp == NULL)
{
perror("malloc fail");
return;
}
int gap = 1;
while (gap < n)
{
//排完所有组
for (int j = 0; j < n; j += gap*2)
{
//printf("gap:%d -> ", gap);
//单趟
int begin1 = j, end1 = begin1 + gap - 1;
int begin2 = begin1 + gap, end2 = begin2 + gap - 1;
int i = j;
//注意end1,begin2,end2是否会越界,begin1 == j肯定不会越界
if (end1 >= n || begin2 >= n)
break;
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])
tmp[i++] = a[begin1++];
else
tmp[i++] = a[begin2++];
}
while (begin1 <= end1)
{
tmp[i++] = a[begin1++];
}
while (begin2 <= end2)
{
tmp[i++] = a[begin2++];
}
//拷贝数组的起始位置和拷贝长度
memcpy(a + j, tmp + j, sizeof(int) * (end2 - j+1));
}
gap *= 2;
}
}