(一)递归调用(函数递归调用),自顶向下
/**
* Merge_Sort: 归并排序的递归实现
* 注:算法导论上给出的合并排序算法
* 递归过程是将待排序集合一分为二,
* 直至排序集合就剩下一个元素为止,然后不断的合并两个排好序的数组
* T(n) = O(nlgn)
**/
#include<stdio.h>
#include<stdlib.h>
void merge(int a[], int start, int mid, int end)
{
int i = 0, j = 0, k = start;
int n1 = mid - start + 1;
int n2 = end - mid;
int *first = (int *)malloc(sizeof(int)*n1);
int *last = (int *)malloc(sizeof(int)*n2);
for (int m = 0; m < n1; m++)
first[m] = a[start + m];
for (int n = 0; n < n2; n++)
last[n] = a[mid + n + 1];
while (i < n1&&j < n2)
{
if (first[i] < last[j])
a[k++] = first[i++];
else
a[k++] = last[j++];
}
if (i < n1)a[k++] = first[i++];
if (j < n2)a[k++] = last[j++];
}
void merge_sort(int a[], int start, int end)
{
int mid ;
if (start < end)
{
mid = (start + end) / 2;
/*分而治之,先分解,在归并*/
merge_sort(a, start, mid);//递归划分原数据左半边
merge_sort(a, mid + 1, end);//递归划分原数据右半边
merge(a, start, mid, end);//归并
}
}
int main()
{
int a[8] = { 1, 2, 4, 5, 3, 9, 7, 8 };
merge_sort(a, 0, 7);
//merge(a, 0, 3, 7);
for (int i = 0; i < 8; i++)
{
printf("%d ", a[i]);
}
return 0;
}
(二)非递归(迭代,循环展开)--自底向上
/**
* merge_sort: 非递归实现 --迭代
* 非递归思想: 将数组中的相邻元素两两配对。用merge函数将他们排序,
* 构成n/2组长度为2的排序好的子数组段,然后再将他们排序成长度为4的子数组段,
* 如此继续下去,直至整个数组排好序。
**/
#include <stdio.h>
#include <stdlib.h>
void merge_sort(int list[], int length)
{
int step, left_min, left_max, right_min, right_max, next;
int *tmp = (int*)malloc(sizeof(int) * length);
if (tmp == NULL)
{
fputs("Error: out of memory\n", stderr);
abort();
}
for (step = 1; step < length; step *= 2) // step为步长,1,2,4,8……
{
for (left_min = 0; left_min < length - step; left_min = right_max)
{
right_min = left_max = left_min + step;
right_max = left_max + step;
if (right_max > length)
right_max = length;
next = 0;
while (left_min < left_max && right_min < right_max)
tmp[next++] = list[left_min] > list[right_min] ? list[right_min++] : list[left_min++];
while (left_min < left_max)
list[--right_min] = list[--left_max];
while (next > 0)
list[--right_min] = tmp[--next];
}
}
free(tmp);
}
int main()
{
int a[8] = { 1, 2, 4, 5, 3, 9, 7, 8 };
merge_sort(a, 8);
for (int i = 0; i < 8; i++)
{
printf("%d ", a[i]);
}
return 0;
}