您的位置:首页 > 其它

分治算法之归并排序

2016-06-09 18:13 429 查看
归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

基本思想

将待排序序列R[0…n-1]看成是n个长度为1的有序序列,将相邻的有序表成对归并,得到n/2个长度为2的有序表;将这些有序序列再次归并,得到n/4个长度为4的有序序列;如此反复进行下去,最后得到一个长度为n的有序序列。

综上可知:

归并排序其实要做两件事:

(1)“分解”——将序列每次折半划分。

(2)“合并”——将划分后的序列段两两合并后排序。

我们先来考虑第二步,如何合并?

在每次合并过程中,都是对两个有序的序列段进行合并,然后排序。这两个有序序列段分别为 R[low, mid] 和 R[mid+1, high]。先将他们合并到一个局部的暂存数组R2中,带合并完成后再将R2复制回R中。为了方便描述,我们称 R[low, mid] 第一段,R[mid+1, high] 为第二段。每次从两个段中取出一个记录进行关键字的比较,将较小者放入R2中。最后将各段中余下的部分直接复制到R2中。经过这样的过程,R2已经是一个有序的序列,再将其复制回R中,一次合并排序就完成了。

算法分析

归并排序算法的性能



归并排序和堆排序、快速排序的比较

(1) 若从空间复杂度来考虑:首选堆排序,其次是快速排序,最后是归并排序。

(2) 若从稳定性来考虑,应选取归并排序,因为堆排序和快速排序都是不稳定的。

(3) 若从平均情况下的排序速度考虑,应该选择快速排序。

伪代码

merge_sort(A,p,q,r)
n1=q-p+1
n2=r-q
let L[1..n1+1]和R[1..n2+1]be new arrays
for i=1 to n1
L[i]=A[p+i-1]
for j=1 to n2
R[j]=A[q+j]
L[n1+1]=∞
R[n2+1]=∞
i=1
j=1
for k=p to r
if L[i]<<R[j]
A[k]=L[i]
i=i+1
else
A[k]= R[j]
j=j+1

merge_sort(A,p,r)
if p<r
q=⌊(p+r)/2⌋
merge_sort(A,p,q)
merge_sort(A,q+1,r)
merge(A,p,q,r)


4.C++代码

#include<iostream>
using namespace std;

template<typename T>
void merge(T *a, int p, int q, int r)
{
int i, j, k=0;
int n1 = q - p + 1;
int n2 = r - q;
T *L = new T[n1];
T *R = new T[n2];
for (i = 0; i < n1; i++)
L[i] = a[p+i];
for (j = 0; j < n2; j++)
R[j] = a[q + 1 + j];
i = 0;
j = 0;
while (i < n1 && j < n2)
{
if (L[i] < R[j])
{
a[p + k] = L[i];
i++;
}
else
{
a[p + k] = R[j];
j++;
}
k++;
}
while (i < n1)
{
a[p + k] = L[i];
i++;
k++;
}
while (j < n2)
{
a[p + k] = R[j];
j++;
k++;
}

delete [] L;
delete [] R;
}

template<typename T>
void merge_sort(T *a, int p, int r)
{
if (p < r)
{
int q = (p + r) / 2;
merge_sort(a, p, q);
merge_sort(a, q + 1, r);
merge(a, p, q, r);
}
}

template <typename T>
void printf_data(T *a, int length)
{
for (int i = 0; i < length; i++)
{
cout << a[i] << " ";
}
cout << endl;
}

int main()
{
int a_int[10] = { 1, 3, 6, 5, 9, 8, 4, 2, 0, 7 };
float a_float[10] = { 1.1, 1.3, 1.5, 1.6, 1.8, 1.9, 1.4, 1.2, 1.0, 1.7 };

printf_data(a_int, 10);
printf_data(a_float, 10);

merge_sort(a_int, 0, 9);
merge_sort(a_float, 0, 9);

printf_data(a_int, 10);
printf_data(a_float, 10);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息