归并算法的本质是将待排序序列分为两部分,依次对分得的两个部分再次使用归并排序,之后再对其进行合并。接下来对待排序列A[0],A[1],A[2],...,A[n-1],用归并排序思想进行排序。
算法实现:
1.将序列分为两部分,其中一部分对应的索引区间为[start1,end1];另一部分的对应的索引区间为[start2,end2]。其中,start1 = 0,end1 = (n - 1)/ 2 (向下取整);
start2 = (n - 1)/ 2 + 1,end2 = n - 1;
2.将上面两个序列按照步骤1再次进行分成四了序列,将四个序列分成八个序列,依次按同样的方法进行下去,知道序列中的元素个数为1时,停止划分序列;
3.将上面所有的序列进行归并排序,排序方法为对所分的n个子序列进行两两合并,得到n/2或n/2+l个含有两个元素的子序列,再对得到的子序列进行合并,直至得到一个长度为n的有序序列为止。
具体流程如下图所示:

待排序列按步骤1进行划分两个序列如下图:

然后将上面2个待排序列化分为4个待排序列如图所示:


依次进行划分知道序列中只有一个元素则停止划分:


划分好后然后进行组合排序:
首先是2个组合排序:

然后再就是4个组合排序:

依次这样组合排序,知道最后序列长度为n - 1,排序后的结果为:

具体代码实现如下所示:
#include<stdio.h>
#include<stdlib.h>
#define arrNum 10
void merge(int arr[], int low, int mid, int high)
{
int i, k;
int* tmp = (int*)malloc((high - low + 1) * sizeof(int));
int left_low = low;
int left_high = mid;
int right_low = mid + 1;
int right_high = high;
for (k = 0; left_low <= left_high && right_low <= right_high; k++)
{
if (arr[left_low] <= arr[right_low]) // 比较两个指针所指向的元素
{
tmp[k] = arr[left_low++];
}
else
{
tmp[k] = arr[right_low++];
}
}
if (left_low <= left_high) //若第一个序列有剩余,直接复制出来粘到合并序列尾
{
//memcpy(tmp+k, arr+left_low, (left_high-left_low+l)*sizeof(int));
for (i = left_low; i <= left_high; i++)
tmp[k++] = arr[i];
}
if (right_low <= right_high) //若第二个序列有剩余,直接复制出来粘到合并序列尾
{
//memcpy(tmp+k, arr+right_low, (right_high-right_low+1)*sizeof(int));
for (i = right_low; i <= right_high; i++)
tmp[k++] = arr[i];
}
for (i = 0; i < high - low + 1; i++)
arr[low + i] = tmp[i];
free(tmp);
}
void merge_sort(int arr[], unsigned int first, unsigned int last)
{
int mid = 0;
if (first < last)
{
mid = (first + last) / 2;
merge_sort(arr, first, mid);
merge_sort(arr, mid + 1, last);
merge(arr, first, mid, last);
}
}
int main()
{
int i;
int a[arrNum] = {2, 1, 6, 8, 7, 4, 3, 2, 9, 0};
printf("排序前:");
for (i = 0; i < arrNum; i++)
printf("%d\t", a[i]);
printf("\n");
merge_sort(a, 0, arrNum - 1); // 排序
printf("排序后:");
for (i = 0; i < arrNum; i++)
printf("%d\t", a[i]);
printf("\n");
system("pause");
return 0;
}代码运行后截图:

版权声明:本文为lipanpan900721原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。