- 归并排序(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]。
- 1. 基本思想
归并排序是用分治思想,分治模式在每一层递归上有三个步骤:
分解(Divide):将n个元素分成个含n/2个元素的子序列。
解决(Conquer):用合并排序法对两个子序列递归的排序。
合并(Combine):合并两个已排序的子序列已得到排序结果。
动图演示:
具体的我们以一组无序数列{14,12,15,13,11,16}为例分解说明,如下图所示:
上图中首先把一个未排序的序列从中间分割成2部分,再把2部分分成4部分,依次分割下去,直到分割成一个一个的数据,再把这些数据两两归并到一起,使之有序,不停的归并,最后成为一个排好序的序列。
代码实现:
#include<iostream>
using namespace std;
void Merge_Sort(int a[],int b[],int left,int right);
void merge(int origin[],int destin[],int left,int middle,int right);
int main()
{
int i,n;
int a[100],b[100];
cin>>n;
for(i=0;i<n;i++)
cin>>a[i];
Merge_Sort(a,b,0,n-1);
for(i=0;i<n-1;i++)
cout<<a[i]<<" ";
cout<<a[i]<<endl;
return 0;
}
//内部使用递归
void Merge_Sort(int a[],int b[],int left,int right)
{
int middle;
if(left<right)
{
middle = (left+right)/2;
Merge_Sort(a,b,left,middle);
Merge_Sort(a,b,middle+1,right);
merge(a,b,left,middle,right); //合并到数组b
}
}
void merge(int origin[],int destin[],int left,int middle,int right)
{
int i=left,j=middle+1,k=left;
while(i<=middle&&j<=right)
{
if(origin[i]<origin[j])
destin[k++]=origin[i++];
else
destin[k++]=origin[j++];
}
//处理剩余元素
while(i<=middle)
destin[k++]=origin[i++];
while(j<=right)
destin[k++]=origin[j++];
for(k=left;k<=right;k++)
origin[k]=destin[k];
}