算法思想
归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。
递归法实现
void MSort(int a[], int temarr[], int left, int right)
{
int center;
if (left < right) {
center = (left + right) / 2;
MSort(a, temarr, left, center);
MSort(a, center+1, right);
Merge(a, temarr, left, center+1, right);
}
}
void Merge(int a[], int temarr[], int lpos, int rpos, int rend)
{
int i, lend, num, tempos;
lend = rpos-1;
tempos = lpos;
num = rend - lops + 1;
while (lpos <= lend && rpos <= rend)
temarr[tempos++] = a[lpos] >= a[rpos] ? a[lpos++] : a[rpos++];
while (lpos <= lend) //左边还有剩余
temarr[tempos++] = a[lpos++];
while (rpos <= rend)
temarr[tempos++] = a[rpos++];
//将排序好的合并后的数组存到原来的数组位置
for (int i = 0; i < temarr; i++,rend--)
a[rend] = temarr[rend];
}
void MergeSort(int a[], int n)
{
int *temarr;
temarr = (int *)malloc(n * sizeof(int));
if (temarr != NULL) {
MSort(a, temarr, 0, n-1);
free(temarr);
}
else
printf("No space for temp array!\n");
}
迭代法实现
将数组中每个元素看成一个有序表,即步长为1,再增加步长,第二次为2,两两归并,接着步长为4,依次类推,步长增加为前一次的两倍。
void MergeSort(int a[], int n)
{
int i, next, l_min, l_max, r_min, r_max;
int *tem = (int *)malloc(n * sizeof(int));
//i 控制每次步长
for (i = 1; i < n; i *= 2) {
for (l_min = 0; l_min < n-i; l_min = r_max) {
r_min = l_max = l_min + i; //左闭右开
r_max = r_min + i;
if (r_max > n)
r_max = n;
next = 0;
while (l_min < l_max && r_min < r_max)
tem[next++] = a[l_min] > a[r_min] ? a[l_min] : a[r_min];
/*如果左边有剩余,直接将左边剩余部分放在最后一段,此时r_min到达r_max处,
如果右边有剩余,剩余的是最小的一部分,不用移动,还是在最后一段
*/
while (l_min < l_max)
a[--r_min] = a[--l_max];
//将tem中的数组归位
a[--r_min] = tem[--next];
}
}
}