归并排序算法

归并排序是利用"归并"技术来进行排序。归并是指将若干个已排序的子文件合并成一个有序的文件。常见的归并排序有两路归并排序(Merge Sort),多相归并排序(Polyphase Merge Sort),Strand排序(Strand Sort)。

两路归并排序(Merge Sort),也就是我们常说的归并排序,也叫合并排序。它是建立在归并操作上的一种有效的排序算法,归并操作即将两个已经排序的序列合并成一个序列的操作。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
归并操作的基本步骤如下:
1.申请两个与已经排序序列相同大小的空间,并将两个序列拷贝其中;
2.设定最初位置分别为两个已经拷贝排序序列的起始位置,比较两个序列元素的大小,依次选择相对小的元素放到原始序列;
3.重复2直到某一拷贝序列全部放入原始序列,将另一个序列剩下的所有元素直接复制到原始序列尾。

设归并排序的当前区间是R[low..high],分治法的三个步骤是:
1.分解:将当前区间一分为二,即求分裂点
2.求解:递归地对两个子区间R[low..mid]和R[mid+1..high]进行归并排序;
3.组合:将已排序的两个子区间R[low..mid]和R[mid+1..high]归并为一个有序的区间R[low..high]。

递归的终结条件:子区间长度为1(一个记录自然有序)。


举例

无序数组[6 2 4 1 5 9]

先看一下每个步骤下的状态,完了再看合并细节

第一步 [6 2 4 1 5 9]原始状态

第二步 [2 6] [1 4] [5 9]两两合并排序,排序细节后边介绍

第三步 [1 2 4 6] [5 9]继续两组两组合并

第四步 [1 2 4 5 6 9]合并完毕,排序完毕

输出结果[1 2 4 5 6 9]

合并细节

详细介绍第二步到第三步的过程,其余类似

第二步:[2 6] [1 4] [5 9]

两两合并,其实仅合并[2 6] [1 4],所以[5 9]不管它,

原始状态

第一个数组[2 6]

第二个数组[1 4]

--------------------

第三个数组[...]



第1步,顺序从第一,第二个数组里取出一个数字:2和1

比较大小后将小的放入第三个数组,此时变成下边这样

第一个数组[2 6]

第二个数组[4]

--------------------

第三个数组[1]



第2步,继续刚才的步骤,顺序从第一,第二个数组里取数据,2和4,

同样的比较大小后将小的放入第三个数组,此时状态如下

第一个数组[6]

第二个数组[4]

--------------------

第三个数组[1 2]



第3步,再重复前边的步骤变成,将较小的4放入第三个数组后变成如下状态

第一个数组[6]

第二个数组[...]

--------------------

第三个数组[1 2 4]



第4步,最后将6放入,排序完毕

第一个数组[...]

第二个数组[...]

--------------------

第三个数组[1 2 4 6]



[ 1 2 4 6 ]与[ 5 9 ]的合并过程与上边一样,不再分解。


例题:

ARR[]= {32,   21,   67};

归并排序算法_第1张图片

示意图如下:


归并排序算法_第2张图片





代码:

// merge_sort.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>

using namespace std;



int d[100] = {0};
//int s[10] = {32, 21, 67, 11, 5, 43, 99, 18, 22, 87};
int s[10] = {32, 21, 67};


void merg(int L, int R)
{
	int mid = (L + R)/2;
	int i = L, j = mid + 1, k = 0;  //i表示前个区的第一个地址,j表示后一个区的第一个地址,k表示新地址

	while (i <= mid && j <= R)
	{
		if(s[i] < s[j])
		{  
			d[k++]=s[i++];  
		}  
		else  
		{  
			d[k++]=s[j++];  
		}   
	}  
	while(i<=mid)d[k++]=s[i++];  
	while(j<=R)d[k++]=s[j++];

	for(i=L,k=0;i<=R;i++,k++)
		s[i]=d[k]; 
	
}


void mergesort(int L,int R)
{
	if (L < R)
	{
		int mid = (L + R)/2;
		mergesort(L, mid);
		mergesort(mid + 1, R);
		merg(L, R);
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	mergesort(0,2);  
	for(int i = 0; i < 10; i++)  
	{  
		cout << s[i] << endl;  
	}  
	return 0;
}


你可能感兴趣的:(归并排序算法)