您的位置:首页 > 其它

归并排序(MERGE-SORT)

2017-07-30 14:23 381 查看
归并排序算法完全遵循分治模式。直观上其操作如下:

分解:分解待排序的n个元素的序列成各具n/2个元素的两个子序列。

解决:除非分解后得到的两个子序列的元素个数为1,否则继续使用归并排序递归地排序两个子序列。

合并:合并两个已排序的子序列以产生已排序的答案。

当待排序的序列长度为1时,递归“开始回升”,在这种情况下不要做任何工作,因为长度为1的每个序列都已排好序。

归并排序算法的关键操作是“合并”步骤中两个已经排序序列的合并。我们通过调用一个辅助过程MERGE(A, low, mid, high)来完成合并,其中A是一个数组,low、mid和high是数组下标,满足low≤mid<high。该过程假设子数组A[low..mid]和A[mid+1..high]都已排好序。它合并这两个子数组形成单一的已排好序的子数组并代替当前的子数组A[low..high]。下面是过程MERGE(A, low, mid, high)的伪代码描述:

MERGE(A,low,mid,high)

1 n1=mid−low+1

2 n2=high−mid

3 let L[1..n1+1] and R[1..n2+1] be new arrays

4 for i=1 to n1

5 L[i]=A[low+i−1]

6 for j=1 to n2

7 R[j]=A[mid+j]

8 i=1

9 j=1

10 for k=low to high

11 if L[i]≤R[j] && i !=n1

12 A[k]=L[i]

13 i=i+1

14 else if R[j]≤L[i] && j !=n2

12 A[k]=R[j]

15 j=j+1

16 if i==n1 || j==n2

17 break

18 if(i==n1)

19 for k=k to high

20 A[k]=R[j]

21 j=j+1

18 else if(j==n2)

19 for k=k to high

20 A[k]=L[i]

21 i=i+1

现在我们可以把过程MERGE作为归并排序算法中的一个子程序来用。下面的过程MERGE-SORT(A, p, r)排序子数组A[p..r]中的元素。若p≥r,则该子数组最多有一个元素,所以已经排好序。否则,分解步骤简单地计算一个下标q,将A[p..r]分成两个子数组A[p..q]和A[q+1..r],前者包含⌈n/2⌉个元素,后者包含⌊n/2⌋个元素。

MERGE−SORT(A,p,r)

1 if p<r

2 q=⌊(p+r)/2⌋

3 MERGE−SORT(A,p,q)

4 MERGE−SORT(A,q+1,r)

5 MERGE(A,p,q,r)

C++实现:

/*归并排序*/
#include <iostream>
using namespace std;

void MergeSort(int* a, int low, int high);
void Merge(int* a, int low, int mid, int high);

void main() {
const int LENGTH = 5;
int a[LENGTH] = { 75,34,93,42,61 };

MergeSort(a, 0, 4);

for(int i=0; i<LENGTH; i++)
cout << a[i] << " ";

system("pause");
}

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);
}
}

void Merge(int * A, int low, int mid, int high) {
int n_1 = mid - low + 1;
int n_2 = high - mid;
int * L = new int[n_1];
int * R = new int[n_2];
int i, j;
for (i = 0; i < n_1; i++) {
L[i] = A[low + i];
}
for (j = 0; j < n_2; j++) {
R[j] = A[mid + j + 1];
}
i = 0;
j = 0;
int k;
for (k = low; k <= high; k++) {
if (L[i] <= R[j] && i < n_1) {
A[k] = L[i];
i++;
}
else if (R[j] <= L[i] && j < n_2) {
A[k] = R[j];
j++;
}
if (i == n_1 || j == n_2) {
k++;
break;
}
}

if (i == n_1) {
for (; k <= high; k++) {
A[k] = R[j++];
}
}
else if (j == n_2) {
for (; k <= high; k++) {
A[k] = L[i++];
}
}

delete[] L, R;
L = NULL;
R = NULL;
}


程序执行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  归并排序 算法 递归