定义: 归并排序(Merge Sort)是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
思想: 先将一个元素个数为n的随机序列进行有限次的分割,每分割一次便得到一个新的序列单元,那么进行有限次的分割以后,则得到n个长度为1的序列单元,相当于将这n个元素分割成一个一个元素,那么在这最小的序列单元中,当前元素就是有序的,无论是最大值还是最小值都是该元素本身,再将两个单元依次进行合并到一个单元中,合并单元的操作为设置两个指针A,B从头开始遍历,如果A指针指向的元素大于B指针指向的元素,那么A指针向后移动,如果B指针指向的元素大于A指针指向的元素,则B指针向后移动,直到两指针有一个到达了自己所指的末尾,然后将为进行完的单元中的元素,依次接到合并后的单元中即可,因为每次的合并都是有序的,所以每个单元中剩下的元素也必然有序。
(聪明的你此时头脑里必然已经有一个递归下探再回溯的过程了)
下探过程:
回溯归并过程:
代码模板:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int vis[N],tmp[N];
int n;
void merge_sort(int vis[],int l,int r)
{
if(l>=r)return;
int mid=(l+r)/2;
merge_sort(vis,l,mid);
merge_sort(vis,mid+1,r);//下探过程
int i=l,j=mid+1,k=1;
while(i<=mid&&j<=r)
{
if(vis[i]<=vis[j])
tmp[k++]=vis[i++];
else tmp[k++]=vis[j++];
}
while(i<=mid)tmp[k++]=vis[i++];
while(j<=r)tmp[k++]=vis[j++];//回溯
for(i=l,j=1;i<=r;i++,j++)vis[i]=tmp[j];
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)cin>>vis[i];
merge_sort(vis,1,n);
for(int i=1;i<=n;i++)printf("%d ",vis[i]);
return 0;
}