算法原理讲解:
归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。
即将要排序的序列进行二分,然后对左右两边进行排序,最后进行合并,而二分的时候,不止一次二分,而是不断分到最后只有一个元素为止。图示如下:
所以对于归并排序主要有两个函数:
1.把一个数组不断的二分,不断的自己调用递归(MergeSort(int a[],int s,int e,int b[]))
2.把二分后的数组,最后根据排序(升序或者降序)进行合并(Merge(int a[],int s,int m,int e,int b[]))
所以这是一个不断递归的处理,再二分的同时,对二分后的结果进行合并排序
算法实现代码(C++):
/*
编写人:Mikchy
时间: 2018/7/26
功能: 实现归并排序,利用分治思想和递归
思路: 1.一个数组分成两部分。
2.两个部分实现分别再递归 归并排序
3.然后将已经排好序的左右两部分合并起来
时间复杂度: O(nlogn),需要多开销一个数组,和要排序的数组等长
*/
#include<iostream>
#include<cstdio>
using namespace std;
int a[100010];
int b[100010];
void Merge(int a[],int s,int m,int e,int b[])
{
// pb用于指向排序的一开头,而p1,p2是两部分的起点
int pb = 0;
int p1 = s,p2 = m+1;
while(p1<=m && p2<=e)
{
// 大的在前面,也就是从大到小排序
if(a[p1] > a[p2])
b[pb++] = a[p1++];
else
b[pb++] = a[p2++];
}
while(p1<=m)
b[pb++] = a[p1++];
while(p2 <= e)
b[pb++] = a[p2++];
// 此时在 b 数组中是排好序的,但是我们需要放回 a 数组中
// 总的长度,e-s+1
// 而 a[] 的开头是要 s ,结尾要是 e
for(int i = 0;i < e-s+1;i++)
a[s+i] = b[i];
}
void MergeSort(int a[],int s,int e,int b[])
{
// 结束排序就是一直分解到最后只剩下一个,也就是 s 和 e两个下标志相等
// 所以只有 s<e 的时候才进行处理
if(s < e)
{
int m = s + (e-s)/2; //中间值 mid = (s+e)/2
// 分成两部分,然后左右两部分也要进行排序
MergeSort(a,s,m,b);
MergeSort(a,m+1,e,b);
// 左右两边排序好了还需要两个合并起来
// 所以要知道的参数,开始s(start),结尾e(end),中间m(middle)
Merge(a,s,m,e,b);
}
}
int main()
{
int n;
scanf("%d",&n);
for(int i = 0;i < n;i++)
scanf("%d",&a[i]);
MergeSort(a,0,n-1,b); // a原数组,长度:0到n-1进行排序,多一个数组b
for(int i = 0;i < n;i++)
printf("%d ",a[i]);
printf("\n");
return 0;
}