归并排序
第一种方法:merge时,新建一个R-L+1长的新数组,把合并后的结果放到新数组,再复制回原数组。
1 #include<iostream> 2 using namespace std; 3 int A[5] = { 5,9,7,2,1 }; 4 void merge(int *A, int l, int m, int r) 5 { 6 int *B = new int[r - l + 1]; 7 int i = l; 8 int j = m + 1; 9 int k = 0; 10 while (i <= m && j <= r) 11 { 12 if (A[i] < A[j]) 13 { 14 B[k++] = A[i++]; 15 } 16 else 17 { 18 B[k++] = A[j++]; 19 } 20 } 21 while (i <= m) 22 { 23 B[k++] = A[i++]; 24 } 25 while (j <= r) 26 { 27 B[k++] = A[j++]; 28 } 29 int x = 0; 30 while (x <= k) 31 { 32 A[l++] = B[x++]; 33 } 34 cout << "----------merge()---------" << endl; 35 cout << "l:" << l << endl; 36 cout << "m:" << m << endl; 37 cout << "r:" << r << endl; 38 for (int i = 0; i < 5; ++i) 39 { 40 cout << A[i] << " "; 41 } 42 cout << endl; 43 free(B); 44 } 45 void mergeSort(int *A, int l, int r) 46 { 47 if (l < r)//递归出口,当分解当序列中只有一个元素后就不再进行分解了 48 { 49 int m = (l + r) / 2; 50 mergeSort(A, l, m); 51 mergeSort(A, m + 1, r); 52 merge(A, l, m, r); 53 } 54 } 55 56 int main22() 57 { 58 59 mergeSort(A, 0, 4); 60 for (int i = 0; i < 5; ++i) 61 { 62 cout << A[i] << endl; 63 } 64 system("pause"); 65 return 0; 66 }
第二种方法:merge时新建左右两个数组,把原数组的左右两半复制到这个新数组里,在两个新数组的基础上把合并结果覆盖到原数组上。
#include<iostream> using namespace std; void merge(int * A, int l, int m, int r) { int *B = new int[m - l + 1]; int *C = new int[r-m]; for (int i = 0; i < m - l + 1; ++i) { B[i] = A[i+l]; } for (int i = 0; i < r-m; ++i) { C[i] = A[i+m+1]; } int i = 0; int j = 0; int k = l; while (i < m - l+1 &&j<r-m) { if (B[i] < C[j]) { A[k++] = B[i++]; } else { A[k++] = C[j++]; } } while (i < m - l+1) { A[k++] = B[i++]; } while (j < r-m) { A[k++] = C[j++]; } free(B); free(C); } void mergeSort(int * A,int l,int r) { if (l < r) { int m = (l + r) / 2; mergeSort(A, l, m); mergeSort(A,m+1,r); merge(A,l,m,r); } } int main() { int A[5] = { 5,2,1,7,3 }; mergeSort(A,0,4); for (int i = 0; i < 5; ++i) { cout << A[i] << endl; } system("pause"); return 0; }
第三种方法:在全局开辟一个原数组的拷贝,合并时在这个全局数组里倒腾,优点:不用每次都开辟新的数组,但是数组复制的这一步还是不能避免。
#include<iostream> #include<time.h> using namespace std; int *a; int *b; int n; void merge(int *a,int s,int m,int e,int *b) { //a[s,m]和a[m+1,e]肯定是有序的 //将数组a的局部a[s,m]和a[m+1,e]合并到tmp,并保证tmp有序,然后再拷贝回a[s,m] int i = s; int j = m+1; int k = 0; while (i <= m && j <= e) { if (a[i] < a[j]) { b[k++] = a[i++]; } else { b[k++] = a[j++]; } } while (i <= m) { b[k++] = a[i++]; } while (j <= e) { b[k++] = a[j++]; } for (int i = 0; i < e - s + 1; ++i) { a[s + i] = b[i]; } } void mergeSort(int *a, int s,int e,int *b) { if (s < e) { int m = (s + e) / 2; mergeSort(a,s,m,b); mergeSort(a,m+1,e,b); merge(a,s,m,e,b); } } void insertSort(int * a) { for (int j = 1; j < n; ++j) { int key = a[j]; int i = j - 1; while (i >= 0 && a[i] > key) { a[i + 1] = a[i]; i--; } a[i + 1] = key; } } int main() { //int n; cout << "输入数组元素个数:" << endl; cin >> n; a1 = (int *)malloc(sizeof(int)*n); srand((unsigned)time(NULL)); for (int i = 0; i < n; ++i) { a1[i] = (rand() % 100); } b = (int *)malloc(sizeof(int)*n); for (int i = 0; i < n; ++i) { b[i] = a[i]; } system("pause"); return 0; }