一.归并排序递归实现
归并递归的思想是,将所有元素分割到最小单位,当元素都是单个时,此时可以认为单个元素是有序的,然后进行壹壹归,之后进行贰贰归、肆肆归(2的倍数)。。。。以此类推最后将所有元素归并为有序。归并的整个过程是比较大小后进行尾插。
1.代码图解
2.代码实现
void MergeSort(int* a,int* tmp, int begin ,int end)
{
if (begin >= end)//b=e代表只有一个元素了,1个默认有序,直接返回。b>e代表已经越界
return;
int mid = (end + begin) / 2;//取中间坐标进行分割
MergeSort(a, tmp, begin, mid);
MergeSort(a, tmp, mid + 1 , end);
int begin1 = begin, end1 = mid;// 11归 --> 22归 -->33归
int begin2 = mid + 1, end2 = end;
int index = begin;
while (begin1 <= end1 && begin2 <= end2)
{
if (a[begin1] < a[begin2])
tmp[index++] = a[begin1++];
if (a[begin2] < a[begin1])
tmp[index++] = a[begin2++];
}
while (begin1 <= end1)
{
tmp[index++] = a[begin1++];
}
while (begin2 <= end2)
{
tmp[index++] = a[begin2++];
}
memcpy(a + begin, tmp + begin, ((end - begin) + 1) * sizeof(int));
}
二.归并排序非递归实现
非递归归并排序的思想是直接先将集合内的元素分成单个进行归并比较尾插,总体实现方法跟递归归并还是一样,只是说没有进行递归,而是用一个下标变量来控制归并的范围,元素还是先进行壹壹归并,然后贰贰归并,叁叁归并、肆肆归并(2的倍数),归并的整个过程是比较大小后进行尾插。
1. 代码图解
2. 代码实现
// 归并排序非递归实现
void MergeSortNonR(int* a, int* tmp, int begin, int end)
{
int gap = 1;
while (gap < end)//gap 1 2 4 8 --> 11归 22归 44归 88归
{
for (int i = 0; i < end; i+=2*gap)// 0 2 4 6 --> 0011 2233 4455 6677
{
int begin1 = i ; int end1 = i + gap - 1;//[0,0 + 1 - 1] == [0,0]
int begin2 = i + gap; int end2 = i + (2 * gap) - 1;//[1,0 + 2 - 1] == [1,1] 这里就是11归
int index = i;
if (begin2 > end)
break;
if (end2 > end)
end2 = end ;
while (begin1 <= end1 && begin2 <= end2)
{
if (a[begin1] < a[begin2])
tmp[index++] = a[begin1++];
if (a[begin2] < a[begin1])
tmp[index++] = a[begin2++];
}
while (begin1 <= end1)
{
tmp[index++] = a[begin1++];
}
while (begin2 <= end2)
{
tmp[index++] = a[begin2++];
}
memcpy(a + i, tmp + i, ((end2 - i) + 1) * sizeof(int));
}
gap *= 2;
}
free(tmp);
}