分治法:将原问题分解成几个规模较小但类似于原问题的子问题,递归的求解这些子问题,然后再合并这些子问题的解来建立原问题的解。
分解:将原问题分解成若干的子问题,这些子问题是原问题的规模较小的实例。
解决:这些子问题,递归的求解个各自问题。如果子问题规模足够小,则直接求解。
合并:这些子问题的解成原问题的解。
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<limits.h> 4 5 void merge(int *a, int p, int q, int r) 6 { 7 int n1 = q - p + 1; //a[p...q] 8 int n2 = r - q; //a[q+1...r] 9 10 int *m = (int *)malloc((n1 + 1) * sizeof(int)); 11 int *n = (int *)malloc((n2 + 1) * sizeof(int)); 12 13 int i = 0, j = 0, k = 0; 14 for (i = p; i <= q; i++) 15 { 16 m[j] = a[i]; 17 j++; 18 } 19 m[j] = INT_MAX; //哨兵牌 20 for (i = q + 1; i <= r; i++) 21 { 22 n[k]= a[i]; 23 k++; 24 } 25 n[k] = INT_MAX; // 哨兵牌 26 27 j = 0, k = 0; 28 for (i = p; i <= r; i++) 29 { 30 if (m[j] <= n[k]) 31 { 32 a[i] = m[j]; 33 j++; 34 } 35 36 else 37 { 38 a[i] = n[k]; 39 k++; 40 } 41 } 42 } 43 void merge_sort(int* a, int p, int r) 44 { 45 int q; 46 47 if (p < r) 48 { 49 q = (p + r) / 2; 50 merge_sort(a, p, q); 51 merge_sort(a, q + 1, r); 52 merge(a, p, q, r); 53 54 } 55 56 } 57 int main() 58 { 59 int matrix[] = { 3,41,52,26,38,57,9,46 }; 60 merge_sort(matrix, 0, 8-1); 61 62 for (int i = 0; i < 8; i++) 63 { 64 printf("%d ", matrix[i]); 65 } 66 return 0; 67 }
不适用哨兵,而是一旦子数组所有元素均被复制回原数组立刻停止,然后把另一个数组的剩余部分复制回原数组。
1 j = 0, k = 0; 2 for (i = p; i <= r; i++) 3 { 4 if (m[j] < n[k] && j < n1) 5 { 6 a[i] = m[j]; 7 j++; 8 } 9 10 else if (n[k]<=m[j] && k < n2) 11 { 12 a[i] = n[k]; 13 k++; 14 } 15 16 else if (j == n1) 17 { 18 a[i] = n[k]; 19 k++; 20 } 21 else if (k == n2) 22 { 23 a[i] = m[j]; 24 j++; 25 } 26 27 }