归并排序原理讲解及C++实现

算法原理讲解:

归并排序(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;
} 

猜你喜欢

转载自blog.csdn.net/mikchy/article/details/81220856
今日推荐