您的位置:首页 > 其它

归并排序(递归与非递归)的实现

2015-09-03 14:08 471 查看
摘要:

(1)归并排序几乎以O(NlogN)的时间界实现,是典型的分治算法;

(2)归并排序的基本思路很简单:就是将目标序列分为两个部分,将两个子序列排序好之后,再将它们合并。注意到合并两个已排序的序列只需要O(N)的时间界。

(3)对两个子序列的排序显然也是通过递归的归并排序实现的。

(4)需要注意的一个小细节是,当子序列的元素很少时,继续调用归并排序未必是一件划算的事.因此可以设置一个边界,当元素个数少于这个值时就掉用最简单的插入排序.

【1】合并的过程

合并的过程相对简单,用两个指针指向两个子序列的开始点,然后比较它们的大小.将较小的一个放入新的数组.然后将指向较小元素的指针前移一位。继续这个过程直到某一个指针达到边界.然后将另一个子序列的剩余所有元素都置入新的数组.

【2】注意的细节:如果每一次递归都创建一个新的数组那么将会占用很多的空间.因此合理的做法是在进入递归之前创建两个数组,然后用两个变量Left,Right标志子序列的边界。每一次合并的过程都是把A[Left1]到A[Right1],A[Left1+1]到A[Right2]合并到B[left1]到B[Right2];

#include "stdafx.h"
#include "malloc.h"
#include "stdlib.h"
#include "string.h"
#define Max 10000000
int Min(int a ,int b)
{
return a < b ? a:b;
}
void Merge(int *A,int *tmp,int Left1,int Right1,int Left2, int Right2)
{
if(Left1==Right1&&Right1==Left2&&Left2==Right2)//只有一个元素不用合并
return;

int point1 = Left1,point2 = Left2,k = Left1;
//int tmp[9];
while(point1 <= Right1 && point2 <= Right2)
{
if(A[point1] <= A[point2])
tmp[Left1++] = A[point1++];
else
tmp[Left1++] = A[point2++];
}
while(point1 <= Right1)
tmp[Left1 ++] = A[point1++];
while(point2 <= Right2)
tmp[Left1++] = A[point2++];
for (Left1 = k;Left1<= Right2;Left1++)
{
A[Left1] = tmp[Left1];
}
}


【2】真正的排序

void Mergesort(int *A,int *tmp,int Left,int Right)
{
int Center;
if(Left == Right)//只有一个元素
return;
Center = (Left + Right)/2;
Mergesort(A,tmp,Left,Center);
Mergesort(A,tmp,Center + 1,Right);
//下面合并
Merge(A,tmp,Left,Center,Center+1,Right);
}


【3】以上的程序都是用递归的办法实现。下面用非递归的办法实现归并排序.

非递归的基本思路

(1)我们应该每次对2^i长度的子序列进行合并。例如最开始对长度为1的相邻子序列进行合并;然后对长度为2的相邻的子序列进行合并。代码如下

void Mergesort2(int *A,int *tmp,int N)
{
//非递归归并
int test[9];

int number = 1;//每次合并个数
int i,Center,end;
while(number <= N-1)
{
for( i = 0;   i + number<= N ; i += number)
{
end = i + number - 1;
Center = (i + end)/2;
Merge(A,tmp,i,Center,Center+1,end);

}
if (i <= N-1)
{
//合并多出的元素
Merge(A,tmp,i-number,i-1,i,N-1);
}
number *= 2;
}
}
void Msort(int A[],int N)
{
int i = 1,cutoff,j;
while(i <= N)
{
i *= 2;
}
cutoff = i - N;
int *B = (int *)malloc(sizeof(int)*i);
int *tmp = (int *)malloc(sizeof(A)*N);
Mergesort2(A,tmp,N);
free(tmp);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: