版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yxw0609131056/article/details/79523495
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路
归并。
归并过程为:比较a[i]和b[j]的大小,若a[i]≤b[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素b[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。
时间复杂度
为O(nlog₂n) 这是该算法中最好、最坏和平均的时间性能。
空间复杂度为 O(n)
比较操作的次数介于(nlogn) / 2和nlogn - n + 1。
赋值操作的次数是(2nlogn)。归并算法的空间复杂度为:0 (n)
归并
排序比较占用内存,但却是一种效率高且稳定的算法。
#include<stdio.h>
#include<stdlib.h>
void merger(int A[],int left,int mid,int right)
{
//创建一个临时数组用于存放合并之后的排序数据
int *temp;
temp = malloc(sizeof(int)*(right-left+1));
if(NULL == temp)
{
printf("Error: out of memory!!\n");
return;
}
//将两个子数组进行合并操作
int i=left,j=mid+1,k=0;
while(i <= mid && j <= right)
{
if(A[i] < A[j])
{
temp[k] = A[i];
i++;
k++;
}
else
{
temp[k] = A[j];
j++;
k++;
}
}
//说明A已经结束,则将B剩余元素复制到C即可
if(i > mid)
{
while(j <= right)
{
temp[k] = A[j];
j++;
k++;
}
}
//说明B已经结束,则将A剩余元素复制到C即可
else
{
while(i <= mid)
{
temp[k] = A[i];
i++;
k++;
}
}
//将临时数组复制到原来数组对应的位置
for(k=0,i=left;i<=right;k++,i++)
A[i] = temp[k];
return;
}
void merger_sort(int a[], int left, int right)
{
//判断数组元素个数是否还可以继续分组,如果元素个数为1,
//则直接进行合并操作
if(left < right)
{
merger_sort(a,left,(left+right)/2);
merger_sort(a,(left+right)/2+1,right);
}
merger(a,left,(left+right)/2,right);
}
int main(void)
{
int i;
int s[] = {6,9,5,8,10,4,1,7,3,2};
printf("------------before merger_sort----------\n");
for(i=0;i<10;i++)
printf("%d ",s[i]);
printf("\n");
merger_sort(s,0,9);
printf("------------after merger_sort----------\n");
for(i=0;i<10;i++)
printf("%d ",s[i]);
printf("\n");
return 0;
}
程序运行结果如下: