《算法导论》CLRS算法C++实现(二)P17 归并排序
第二章 算法入门
两个有序数组的合并
这个算法我的实现跟算法导论上的实现有些许区别。我没有使用《算法导论》上的哨兵位的方法。而且直接判断有没有到数组的末尾。不过为了跟书上保持一致,我的伪代码还是使用算法导论上的伪代码。
算法描述:
MERGE(A, p, q, r)是把存储在A[p...q]和A[q+1...r]这两部分中的有序子序列合并到A[p...r]并使其有序。
两个子数组的长度分别为int n1=q-p+1; int n2=r-q; 建立两个新数组L和R,用于分别存放原数组的两个有序部分。分别遍历两个新的数组L和R,依次比较其中元素,将其中较小的元素存放到原数组A的对应位置。L和R中任何一个数组遍历结束后,将另一个数组的剩余部分复制到原数组A的后面位置。至此算法完成。
伪代码实现
MERGE(A, p, q, r) 《算法导论》P17
1 n1 ← q - p + 1 2 n2 ← r - q 3 create arrays L[1 ‥ n1 + 1] and R[1 ‥ n2 + 1] 4 for i ← 1 to n1 5 do L[i] ← A[p + i - 1] 6 for j ← 1 to n2 7 do R[j] ← A[q + j] 8 L[n1 + 1] ← ∞ 9 R[n2 + 1] ← ∞ 10 i ← 1 11 j ← 1 12 for k ← p to r 13 do if L[i] ≤ R[j] 14 then A[k] ← L[i] 15 i ← i + 1 16 else A[k] ← R[j] 17 j ← j + 1
MERGE-SORT(A, p, r) 《算法导论》 P19
1 if p < r 2 then q ← floor((p + r)/2) 3 MERGE-SORT(A, p, q) 4 MERGE-SORT(A, q + 1, r) 5 MERGE(A, p, q, r)
C++代码实现
1 #include <iostream> 2 3 using namespace std; 4 5 void merge(int*arr, int p, int q, int r) 6 { 7 int n1 = q - p + 1; 8 int n2 = r - q; 9 10 int* L = new int[n1]; 11 int* R = new int[n2]; 12 13 for(int i = 0; i < n1; i++) 14 { 15 L[i] = arr[p + i]; 16 } 17 for(int j = 0; j < n2; j++) 18 { 19 R[j] = arr[q + j + 1]; 20 } 21 22 int i = 0; 23 int j = 0; 24 int k = p; 25 26 while((i < n1) && (j < n2)) 27 { 28 if(L[i] <= R[j]) 29 { 30 arr[k] = L[i]; 31 i++; 32 } 33 else 34 { 35 arr[k] = R[j]; 36 j++; 37 } 38 k++; 39 } 40 41 if (i < n1) 42 { 43 for(; i < n1; i++, k++) 44 { 45 arr[k] = L[i]; 46 } 47 } 48 if (j < n2) 49 { 50 for(; j < n2; j++, k++) 51 { 52 arr[k] = R[j]; 53 } 54 } 55 } 56 57 void mergesort(int* arr, int p, int r) 58 { 59 int q = 0; 60 if(p < r) 61 { 62 q = (p + r) / 2; 63 mergesort(arr, p, q); 64 mergesort(arr, q + 1, r); 65 merge(arr, p, q, r); 66 } 67 } 68 69 int main() 70 { 71 int a[] = {2, 45, 5, 7, 34, 456, 345, 89, 8, 1, 341, 4, 98, 67}; 72 mergesort(a, 0, 13); 73 for(int i = 0; i < 14; i++) 74 { 75 cout << a[i] << " "; 76 } 77 cout << endl; 78 return 0; 79 }