归并排序
归并排序(Merge Sort)就是利用分治法的思想实现的排序方法。它的原理是假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两辆归并,得到得到个n/2个长度为2或者1的有序子序列;两两再归并,……,如此重复,直到得到一个长度为n的有序序列为止,这种排序方法称为2路归并排序,属于稳定排序。
例如数组A有7个数据,分别是: 49 38 65 97 76 13 27,那么采用归并排序算法的操作过程如图7所示:
初始值 [49] [38] [65] [97] [76] [13] [27]
看成由长度为1的7个子序列组成
第一次合并之后 [38 49] [65 97] [13 76] [27]
看成由长度为1或2的4个子序列组成
第二次合并之后 [38 49 65 97] [13 27 76]
看成由长度为4或3的2个子序列组成
第三次合并之后 [13 27 38 49 65 76 97]
归并算法的核心操作就是将一维数组中前后相邻的两个两个有序序列合并成一个有序序列。归并算法也可以采用递归算法来实现,形式上较为简单,但实用性很差。归并算法的归并次数是一个非常重要的量,根据计算当数组中有3到4个元素时,归并次数是2次,当有5到8个元素时,归并次数是3次,当有9到16个元素时,归并次数是4次,按照这一规律,当有N个子序列时可以推断出归并的次数是X(2 >=N,符合此条件的最小那个X)。
其时间复杂度为:O(nlogn).所需辅助存储空间为:O(n)
递归版本代码
#include
#include
using namespace std;
void Merge(int a[], int low, int mid, int high){
//没有必要每次动态申请,可以声明为全局的
int *tmp = (int *)malloc((high - low + 1)*sizeof(int));
int i = low, j = mid + 1;
int p = 0;
while(i<=mid && j<=high){
tmp[p++] = a[i] < a[j] ? a[i++] : a[j++];
}
while(i<=mid){
tmp[p++] = a[i++];
}
while(j<=high){
tmp[p++] = a[j++];
}
for(p=0, i=low; i<=high;){
a[i++] = tmp[p++];
}
free(tmp);
}
void MergeSort(int a[], int low, int high){
if(low < high){
int mid = (low + high)/2;
MergeSort(a, low, mid);
MergeSort(a, mid+1, high);
Merge(a, low, mid, high);
}
}
int main(){
int a[] = {1, 3, 9, 2, 6, 5, 4, 8, 7, 0};
cout << "Original array: " << endl;
for(int i=0; i<9; i++)
cout << a[i] << " ";
cout << a[9] << endl;
MergeSort(a, 0, 9);
cout << "MergeSorted array: " << endl;
for(int i=0; i<9; i++)
cout << a[i] << " ";
cout << a[9] << endl;
return 0;
}