`
java-mans
  • 浏览: 11430767 次
文章分类
社区版块
存档分类
最新评论

《算法之美》---归并排序

 
阅读更多

将一个大序列的排序问题分解为对两个或多个子序列的排序问题,然后对子序列递归使用同样的方式进行排序;在子序列排好序后,将结果合并起来即可。利用这种思想的排序方法就是著名的归并排序。之所以称为归并排序,是因为整个算法的成本由归并部分决定。

归并算法描述如下:

1)如果n=1,排序完成;

2)将序列分解为两个子序列A[1 ceiling(n/2)]A[ceiling(n/2)+1 n]

3)递归对子序列A[1 ceiling(n/2)]A[ceiling(n/2)+1 n]进行排序;

4)将排好序的两个子序列进行归并。

归并排序使用的是分治策略,而分治策略的关键是分解和合并。归并排序的分解很简单:直接将序列从中间斩断;但合并的时候需要将两个排好序的子序列按次序进行合适的穿插,从而获得原序列的一个排序。

合并时我们使用两个指针:一个指向A序列里下一个要归并的元素,一个指向B序列里下一个要归并的元素。每步我们对这两个指针所指的元素进行比较,小者被归并到C序列里,并将指向较小者的指针往后推进一个元素,另一个指针保持不动。这样循环往复直到一个子序列为空。这时,另一个子序列中剩下的所有元素直接复制到C序列末尾即可。

注意:归并排序在最坏、平均和最好情况下时间复杂度都是Θ(nlogn)。这是归并排序一个显著的特点:一视同仁。

/*

函数名: MergeSort

功能: 归并排序

模板参数说明:T必须支持小于操作

参数说明: data待排序数组, size待排序数组大小

前置条件: data!=NULL, size>0

后置条件: data按非降序排列

用法:

#include <algorithm>

int arr[]={10,9,8,4,5,7,6,3,1,4};

MergeSort(arr, 10);

*/

template <typename T>

void MergeSort (T data[], int size)

{

if ( size>1 )

{

//预处理

int mid=size/2;

int numOfleft=mid;

int numOfright=size-mid;

T* left=new T[numOfleft];

T* right=new T[numOfright];

//分解

std::copy(data, data+numOfleft, left);

std::copy(data+numOfleft, data+size, right);

MergeSort(left, numOfleft);

MergeSort(right, numOfright);

//合并

std::merge(left, left+numOfleft, right, right+numOfright, data);

//清理

delete[] left;

delete[] right;

}

}

/*

函数名: MergeSort

功能: 归并排序

模板参数说明:T元素类型, Func函数对象或指针

参数说明: data待排序数组, size待排序数组大小,f函数对象或指针

前置条件: data!=NULL, size>0

后置条件: dataf排列

用法:

#include <algorithm>

bool cmp(int a, int b)

{ return a<b; }

int arr[]={10,9,8,4,5,7,6,3,1,4};

MergeSort(arr, 10cmp);

*/

template <typename T, typename Func>

void MergeSort (T data[], int size, Func f)

{

if ( size>1 )

{

int mid=size/2;

int numOfleft=mid;

int numOfright=size-mid;

T* left=new T[numOfleft];

T* right=new T[numOfright];

std::copy(data, data+numOfleft, left);

std::copy(data+numOfleft, data+size, right);

MergeSort(left, numOfleft, f);

MergeSort(right, numOfright, f);

std::merge(left, left+numOfleft, right, right+numOfright, data, f);

delete[] left;

delete[] right;

}

}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics