思想:
- 分治思想——把一个复杂庞大的问题分解成一个个小的问题去解决(就好比辅导员管班长,班长管寝室长,寝室长管寝室成员)
- 归并排序,就是将待排序的数分成两半后排好序,然后再将两个排好序的序列合并成一个有序序列
- 需要开辟辅助空间,在合并时运用(如下图,假设将最后的arr看成新的空间,就是不断取出最小的元素放在里面比较一下,取完后这个新空间里的元素有序)
阅读篇:慧能大师讲解归并排序
看图入门:
代码实现(难度在合并,理解后还算简单):
//将a[left...center]和a[center+1...right]两个有序数组合并成一个有序数组
void merge(int a[],int tmp[],int left,int center,int right)
{
int i=left;
int j=center+1;
//比较结果暂放入tmp
for(int k=left;k<=right;k++)
{
//若左边数组取完,则比较完成,直接将右边数组copy到临时数组
//右边数组同理
if(i>center)
{
tmp[k]=a[j++];
}
else if(j>right)
{
tmp[k]=a[i++];
}
else if(a[i]<=a[j])
{
tmp[k]=a[i++];
}
else
{
tmp[k]=a[j++];
}
}
//再将排好序的临时数组回copy
for(int h=left;h<=right;h++)
{
a[h]=tmp[h];
}
}
void MergeSort(int a[],int tmp[],int left,int right)
{
if(left<right)
{
//[分]:数组一分为二
int center=(left+right)/2;
//[治]:将左边数组排序
MergeSort(a,tmp,left,center);
//[治]:将右边数组排序
MergeSort(a,tmp,center+1,right);
//[合]:合并两个有序数组
merge(a,tmp,left,center,right);
}
}