归并排序是典型的分治算法的例子,即先使每个子序列有序,再使子序列段间有序
归并排序的时空复杂度
1、归并排序的时间复杂度
归并排序的平均时间性能O(nlogn) 。
2、归并排序的空间复杂度
归并排序的空间复杂度为:O(n)。
算法思想
归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。
一趟归并的操作如下:
第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置
第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针超出序列尾
算法示意图:
自己的代码实现:
#include <stdio.h>
int num1[10000];
int num2[10000];
void copy(int left,int right);
void Merge(int left,int m,int right);
void MergeSort(int left,int right);
int main()
{
int n;
int i;
printf("Please input the number of the data:\n");
scanf("%d",&n);
printf("Please input the data:\n");
for(i = 0;i < n;i++)
scanf("%d",&num1[i]);
MergeSort(0, n-1);
for(i = 0;i < n;i++)
printf("%d ",num1[i]);
printf("\n");
return (0);
}
void MergeSort(int left,int right)
{
if(left < right)
{
int i = (left + right)/2; //将当前数列分为两组
MergeSort(left, i); //归并排序左边数列
MergeSort(i+1, right); //归并排序右边数列
Merge(left, i, right); //归并左右两组已经排序好的数列
copy(left, right); //归并的结果copy回num1[]数组
}
}
void Merge(int left,int m,int right)
{
int i = left;
int j = m+1;
int k = left;
while(i <= m && j <= right)
{
if( num1[i] < num1[j])
num2[k++] = num1[i++];
else
num2[k++] = num1[j++];
}
int q;
if(i > q)
for(q = j;q <= right;q++ )
num2[k++] = num1[q];
else
for(q = i;q <= m;q++)
num2[k++] = num1[q];
}
void copy(int left,int right)
{
if(left < right)
{
int i;
for(i = left;i <= right;i++)
num1[i] = num2[i];
}
}