归并排序(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++实现:
程序执行结果:
分解:分解待排序的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; }
程序执行结果:
相关文章推荐
- 归并排序(Merge Sort)
- 归并排序(mergeSort)之非递归算法
- 二路归并排序(Merge Sort)
- Java 归并排序(MergeSort)算法实现
- 归并排序(MergeSort)的原理及延伸性思考
- MergeSort(归并排序)算法Java实现
- 归并排序(Merge-Sort)的C语言实现
- 归并排序(merge_sort)的C语言实现
- 归并排序(MergeSort)的原理及延伸性思考
- Mergesort-归并排序
- 归并排序(mergeSort) 与 分而治之策略(divide and conquer)
- 归并排序(MergeSort)
- Natural Merge Sort(自然归并排序)
- 归并排序(merge sort)的实现
- 排序算法详解【归并排序-Merge_Sort】
- 自顶向下归并排序(Merge Sort)
- 排序算法之归并排序(Mergesort)解析
- 归并排序(Merge Sort)递归、非递归 Java实现
- 归并排序(MergeSort)
- 归并排序(merge sort)