1.背包问题 1.1递归 1.1.1普通递归方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 const int maxn = 1000 ;int w[maxn], c[maxn], dp[maxn];int solve (int w[], int c[], int index, int capacity) { if (index < 0 || capacity <= 0 ) return 0 ; int res = solve (w, c, index - 1 , capacity); if (w[index] <= capacity) { res = max (res, c[index] + solve (w, c, index - 1 , capacity - w[index])); } return res; } int main () { int n, capacity; scanf ("%d%d" , &n, &capacity); for (int i = 1 ; i <= n; i++) { scanf ("%d" , &w[i]); } for (int i = 1 ; i <= n; i++) { scanf ("%d" , &c[i]); } int x = solve (w, c, n, capacity); cout << "x=" << x << endl; return 0 ; }
1.1.2记忆化搜索递归 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 const int maxn = 1000 ;int w[maxn], c[maxn], dp[maxn];int memo[maxn][maxn];int solve (int w[], int c[], int index, int capacity) { if (index < 0 || capacity <= 0 ) return 0 ; int res = solve (w, c, index - 1 , capacity); if (memo[index][capacity] != 0 ) { return memo[index][capacity]; } if (w[index] <= capacity) { res = max (res, c[index] + solve (w, c, index - 1 , capacity - w[index])); } memo[index][capacity] = res; return res; } int main () { int n, capacity; scanf ("%d%d" , &n, &capacity); for (int i = 1 ; i <= n; i++) { scanf ("%d" , &w[i]); } for (int i = 1 ; i <= n; i++) { scanf ("%d" , &c[i]); } int x = solve (w, c, n, capacity); cout << "x=" << x << endl; return 0 ; }
1.2.动态规划算法 1.2.1下标从1开始 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 const int maxn = 100 ;int w[maxn] = { 0 }, c[maxn] = { 0 }, dp[maxn] = { 0 };int main () { int n, capacity; scanf ("%d%d" , &n, &capacity); int a[30 ][30 ] = {0 }; for (int i = 1 ; i <= n; i++) { scanf ("%d" , &w[i]); } for (int i = 1 ; i <= n; i++) { scanf ("%d" , &c[i]); } for (int i = 1 ; i <= n; i++) { for (int j = 1 ; j <= capacity; j++) { if (j < w[i]) { a[i][j] = a[i - 1 ][j]; } else { a[i][j] = max (a[i - 1 ][j], a[i - 1 ][j - w[i]] + c[i]); } } } int max = a[1 ][1 ]; for (int i = 0 ; i <= n; i++) { for (int j = 0 ; j <= capacity; j++) { if (a[i][j] > max) { max = a[i][j]; } } } printf ("max=%d\n" , max); return 0 ; }
1.2.2下标从0开始 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 const int maxn = 100 ;int w[maxn] = { 0 }, c[maxn] = { 0 }, dp[maxn] = { 0 };int main () { int n, capacity; scanf ("%d%d" , &n, &capacity); vector<vector<int > > a (n + 1 , vector <int >(capacity + 1 )); for (int i = 0 ; i < n; i++) { scanf ("%d" , &w[i]); } for (int i = 0 ; i < n; i++) { scanf ("%d" , &c[i]); } for (int i = 0 ; i <= capacity; i++) { if (w[0 ] < i) { a[0 ][i] = c[0 ]; } else { a[0 ][i] = 0 ; } } for (int i = 1 ; i < n; i++) { for (int j = 0 ; j <= capacity; j++) { if (j < w[i]) { a[i][j] = a[i - 1 ][j]; } else { a[i][j] = max (a[i - 1 ][j], a[i - 1 ][j - w[i]] + c[i]); } } } int max = a[0 ][0 ]; for (int i = 0 ; i < n; i++) { for (int j = 0 ; j <= capacity; j++) { if (a[i][j] > max) { max = a[i][j]; } } } printf ("max=%d\n" , max); return 0 ; }
1.3.深度优先搜索 1.3.1常规算法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 const int maxn = 30 ;int n, V, maxvalue = 0 ; int w[maxn], c[maxn]; void DFS (int index, int sumw, int sumc) { if (index == n) { if (sumw <= V && sumc > maxvalue) { maxvalue = sumc; } retusrn; } DFS (index + 1 , sumw, sumc); DFS (index + 1 , sumw + w[index], sumc + c[index]); } int main () { scanf ("%d%d" , &n, &V); for (int i = 0 ; i < n; i++) { scanf ("%d" , &w[i]); } for (int i = 0 ; i < n; i++) { scanf ("%d" , &c[i]); } DFS (0 , 0 , 0 ); printf ("%d\n" , maxvalue); return 0 ; }
1.3.2优化时间复杂度(剪枝) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 const int maxn = 30 ;int n, V, maxvalue = 0 ; int w[maxn], c[maxn]; void DFS (int index, int sumw, int sumc) { if (index == n) { return ; } DFS (index + 1 , sumw, sumc); if (sumw + w[index] <= V) { if (sumc + c[index] > maxvalue) { maxvalue = sumc + c[index]; } DFS (index + 1 , sumw + w[index], sumc + c[index]); } } int main () { scanf ("%d%d" , &n, &V); for (int i = 0 ; i < n; i++) { scanf ("%d" , &w[i]); } for (int i = 0 ; i < n; i++) { scanf ("%d" , &c[i]); } DFS (0 , 0 , 0 ); printf ("%d\n" , maxvalue); return 0 ; }
2.贪心算法 2.1.活动选择问题 有n个需要在同一天使用同一个教室的活动a1,a2,…,an,教室同一时刻只能由一个活动使用。每个活动ai都有一个开始时间si和结束时间fi 。一旦被选择后,活动ai就占据半开时间区间[si,fi)。如果[si,fi]和[sj,fj]互不重叠,ai和aj两个活动就可以被安排在这一天。该问题就是要安排这些活动使得尽量多的活动能不冲突的举行。例如下图所示的活动集合S,其中各项活动按照结束时间单调递增排序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 #include <iostream> #include <algorithm> using namespace std;const int maxn = 200 ;struct aa { int start; int end; }; bool cmp (aa x, aa y) { return x.end < y.end; } void src (int n, aa s[], bool a[]) { a[1 ] = true ; int j = 1 ; for (int i = 2 ; i <= n; i++) { if (s[i].start > s[j].end) { a[i] = true ; j = i; } else { a[i] = false ; } } } int main () { int n; aa s[maxn]; bool a[maxn] = { false }; cin >> n; for (int i = 1 ; i <= n; i++) { cin >> s[i].start; } for (int i = 1 ; i <= n; i++) { cin >> s[i].end; } sort (s + 1 , s + 1 + n, cmp); src (n, s, a); cout << endl; for (int i = 1 ; i <= n; i++) { cout << a[i] << " " ; } cout << endl; }
2.2.最优装载问题 有一批集装箱要装上一艘载重量为c的轮船。其中集装箱i的重量为Wi。最优装载问题要求确定在装载体积不受限制的情况下,将尽可能多的集装箱装上轮船。(意思就是在不超过载重量的情况下最多能装多少)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #include <iostream> #include <algorithm> #include <vector> using namespace std;const int maxn = 300 ;int main () { int weigh[maxn]; int num; int max; int result[maxn]; int sum = 0 ; int count = 1 ; cout << "请输入船的最大载重量" << endl; cin >> max; cout << "请输入集装箱的数量" << endl; cin >> num; cout << "请输入每个集装箱的重量" << endl; for (int i = 1 ; i <= num; i++) { cin >> weigh[i]; } sort (weigh + 1 , weigh + 1 + num); for (int i = 1 ; i <= num; i++) { sum = sum + weigh[i]; if (sum <= max) { result[count] = weigh[i]; count++; } else { break ; } } cout << "可装载货物的重量分别为:" << endl; for (int i = 1 ; i < count; i++) { cout << result[i] << " " ; } cout << endl; return 0 ; }
3.递归与分治问题 3.1.n皇后问题 N皇后问题是一个经典的问题,在一个N*N的棋盘上放置N个皇后,每行一个并使其不能互相攻击(同一行、同一列、同一斜线上的皇后都会自动攻击)。
3.1.1暴力法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #include <iostream> using namespace std;const int maxn = 100 ;int count1 = 0 ;int n, p[maxn], hashtable[maxn] = { false };void generatep (int index) { if (index == n + 1 ) { bool flag = true ; for (int i = 1 ; i <= n; i++) { for (int j = i + 1 ; j <= n; j++) { if (abs (i - j) == abs (p[i] - p[j])) { flag = false ; } } if (flag) { count1++; } return ; } for (int x = 1 ; x <= n; x++) { if (hashtable[x] == false ) { p[index] = x; hashtable[x] = true ; generatep (index + 1 ); hashtable[x] = false ; } } } int main () { cout << "请输入棋盘的行列数" << endl; cin >> n; generatep (1 ); cout << count1 << endl; }
3.1.2回溯法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 #include <iostream> using namespace std;const int maxn = 100 ;int count1 = 0 ;int n, p[maxn], hashtable[maxn] = { false };void generatep (int index) { if (index == n + 1 ) { count1++; return ; } for (int x = 1 ; x <= n; x++) { if (hashtable[x] == false ) { bool flag = true ; for (int pre = 1 ; pre < index; pre++) { if (abs (index - pre) == abs (x - p[pre])) { flag = false ; break ; } } if (flag) { p[index] = x; hashtable[x] = true ; generatep (index + 1 ); hashtable[x] = false ; } } } } int main () { cout << "请输入棋盘的行列数" << endl; cin >> n; generatep (1 ); cout << count1 << endl; }
3.2.二分搜索 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #include <iostream> int binarysearch (int a[], int left, int right, int x) { int mid; while (left <= right) { mid = (left + right) / 2 ; if (a[mid] == x) { return mid; } else if (a[mid] > x) { right = mid - 1 ; } else { left = mid + 1 ; } } return -1 ; } int main () { int x; int a[8 ] = { 0 ,5 ,7 ,1 ,4 ,2 ,7 ,4 }; x = binarysearch (a, 0 , 7 , 1 ); cout << x << endl; cout << endl; }
3.3.棋盘覆盖问题 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 #include <iostream> using namespace std; int tile=1 ; int board[100 ][100 ]; void chessBoard ( int tr, int tc, int dr, int dc, int size ) { if ( size==1 ) return ; int t=tile++; int s=size/2 ; if ( dr<tr+s && dc<tc+s ) chessBoard ( tr, tc, dr, dc, s ); else { board[tr+s-1 ][tc+s-1 ]=t; chessBoard ( tr, tc, tr+s-1 , tc+s-1 , s ); } if ( dr<tr+s && dc>=tc+s ) chessBoard ( tr, tc+s, dr, dc, s ); else { board[tr+s-1 ][tc+s]=t; chessBoard ( tr, tc+s, tr+s-1 , tc+s, s ); } if ( dr>=tr+s && dc<tc+s ) chessBoard ( tr+s, tc, dr, dc, s ); else { board[tr+s][tc+s-1 ]=t; chessBoard ( tr+s, tc, tr+s, tc+s-1 , s ); } if ( dr>=tr+s && dc>=tc+s ) chessBoard ( tr+s, tc+s, dr, dc, s ); else { board[tr+s][tc+s]=t; chessBoard ( tr+s, tc+s, tr+s, tc+s, s ); } } void main () { int size; cout<<"输入棋盘的size(大小必须是2的n次幂): " ; cin>>size; int index_x,index_y; cout<<"输入特殊方格位置的坐标: " ; cin>>index_x>>index_y; chessBoard ( 0 ,0 ,index_x,index_y,size ); for ( int i=0 ; i<size; i++ ) { for ( int j=0 ; j<size; j++ ) cout<<board[i][j]<<'/t' ; cout<<endl; } }
3.4.循环赛日程表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 #include <iostream> using namespace std;#define N 50 void print (int n, int game[][N]) { for (int i = 0 ; i < n; i++) { for (int j = 0 ; j < n; j++) { cout << game[i][j] << '\t' ; } cout << endl; } } void arrange (int p, int q, int t, int arr[][N]) { if (t >= 4 ) { arrange (p, q, t / 2 , arr); arrange (p, q + t / 2 , t / 2 , arr); } for (int i = p + t / 2 ; i < p + t; i++) { for (int j = q; j < q + t / 2 ; j++) { arr[i][j] = arr[i - t / 2 ][j + t / 2 ]; } } for (int i = p + t / 2 ; i < p + t; i++) { for (int j = q + t / 2 ; j < q + t; j++) { arr[i][j] = arr[i - t / 2 ][j - t / 2 ]; } } } int main () { int n; int game[N][N]; cout << "请输入选手人数:" << endl; cin >> n; for (int i = 0 ; i < n; i++) { for (int j = 0 ; j < n; j++) { if (i == 0 ) game[i][j] = j + 1 ; else game[i][j] = 0 ; } } arrange (0 , 0 , n, game); print (n, game); system ("pause" ); return 0 ; }
3.5.马拦过河卒 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #include <iostream> using namespace std;int total; int end_r,end_c; int hourse_r,hourse_c; int wayr[2 ]={1 ,0 },wayc[2 ]={0 ,1 }; int territory[9 ][2 ]={{0 ,0 },{1 ,2 },{1 ,-2 },{-1 ,2 },{-1 ,-2 },{2 ,1 },{2 ,-1 },{-2 ,1 },{-2 ,-1 }}; bool map[20 ][20 ]; bool check (int x,int y) { if (x>end_r||y>end_c) return 0 ; return 1 ; } void dfs (int r,int c) { for (int i=0 ;i<2 ;i++) if (check (r+wayr[i],c+wayc[i])&&!map[r+wayr[i]][c+wayc[i]]) { r+=wayr[i]; c+=wayc[i]; if (r==end_r&&c==end_c) total++; else dfs (r,c); r-=wayr[i]; c-=wayc[i]; } } int main () { cin>>end_r>>end_c>>hourse_r>>hourse_c; for (int i=0 ;i<9 ;i++) map[hourse_r+territory[i][0 ]][hourse_c+territory[i][1 ]]=1 ; dfs (0 ,0 ); cout<<total; }
4,动态规划 4.1.矩阵连乘问题 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 #include <iostream> using namespace std;const int N = 100 ;int A[N];int m[N][N];int s[N][N];void MatrixChain (int n) { int r, i, j, k; for (i = 0 ; i <= n; i++) { m[i][i] = 0 ; } for (r = 2 ; r <= n; r++) { for (i = 1 ; i <= n - r + 1 ; i++) { j = i + r - 1 ; m[i][j] = m[i][i]+m[i + 1 ][j] + A[i - 1 ] * A[i] * A[j]; s[i][j] = i; for (k = i + 1 ; k < j; k++) { int t = m[i][k] + m[k + 1 ][j] + A[i - 1 ] * A[k] * A[j]; if (t < m[i][j]) { m[i][j] = t; s[i][j] = k; } } } } } void print (int i, int j) { if (i == j) { cout << "A[" << i << "]" ; return ; } cout << "(" ; print (i, s[i][j]); print (s[i][j] + 1 , j); cout << ")" ; } int main () { int n; cin >> n; int i, j; for (i = 0 ; i <= n; i++) { cin >> A[i]; } MatrixChain (n); cout << "最佳添加括号的方式为:" ; print (1 , n); cout << "\n最小计算量的值为:" << m[1 ][n] << endl; return 0 ; }
4.2.最长公共子序列 给定两个字符串(或数字序列)A和B,求一个字符串,使得这个字符串是A和B的最长公共部分(子序列可以不连续)
eg:字符串”sadstory”和”adminsorry”的最长公共子序列为”adsory”,长度为6
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std;const int maxn = 100 ;char a[maxn], b[maxn];int dp[maxn][maxn];int main () { int n; gets_s (a + 1 , maxn); gets_s (b + 1 , maxn); int lena = strlen (a + 1 ); int lenb = strlen (b + 1 ); for (int i = 0 ; i <= lena; i++) { dp[i][0 ] = 0 ; } for (int j = 0 ; j <= lenb; j++) { dp[0 ][j] = 0 ; } for (int i = 1 ; i <= lena; i++) { for (int j = 1 ; j <= lenb; j++) { if (a[i] == b[j]) { dp[i][j] = dp[i - 1 ][j - 1 ] + 1 ; } else { dp[i][j] = max (dp[i - 1 ][j], dp[i][j - 1 ]); } } } cout << dp[lena][lenb] << endl; }
4.3.数塔问题 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <iostream> #include <algorithm> using namespace std;const int maxn = 100 ;int main () { int n; int f[maxn][maxn], dp[maxn][maxn]; cin >> n; for (int i = 1 ; i <= n; i++) { for (int j = 1 ; j <= i; j++) { cin >> f[i][j]; } } for (int j = 1 ; j <= n; j++) { dp[n][j] = f[n][j]; } for (int i = n - 1 ; i >= 1 ; i--) { for (int j = 1 ; j <= i; j++) { dp[i][j] = max (dp[i + 1 ][j], dp[i + 1 ][j + 1 ]) + f[i][j]; } } cout << dp[1 ][1 ] << endl; return 0 ; }
4.4.最大连续子序列和 给定一个数字序列A1,A2,…..,An,求i,j(1<=i<=j<=n),使得Ai+…+Aj最大,输出这个最大和
eg:-2 11 -4 13 -5 -2 显然最大和为20
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <iostream> #include <algorithm> using namespace std;const int maxn = 100 ;int src[maxn];int dp[maxn];int main () { int n; cin >> n; for (int i = 0 ; i < n; i++) { cin >> src[i]; } dp[0 ] = src[0 ]; for (int i = 1 ; i < n; i++) { dp[i] = max (src[i], dp[i - 1 ] + src[i]); } int k = 0 ; for (int i = 1 ; i < n; i++) { if (dp[i] > dp[k]) { k = i; } } cout << dp[k] << endl; }
5.常见排序 5.1.选择排序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <iostream> #include <algorithm> #include <vector> using namespace std;const int maxn = 100 ;void selectsort (int a[], int n) { for (int i = 0 ; i < n; i++) { int k = i; for (int j = i; j < n; j++) { if (a[j] < a[k]) { k = j; } } swap (a[i], a[k]); } } int main () { int a[maxn] = { 3 ,5 ,1 ,7 ,9 ,0 ,3 ,5 }; selectsort (a, 8 ); for (int i = 0 ; i < 8 ; i++) { cout << a[i] << " " ; } cout << endl; }
5.2.插入排序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <iostream> #include <algorithm> #include <vector> using namespace std;const int maxn = 100 ;void insertsort (int a[], int n) { for (int i = 1 ; i < n; i++) { int temp = a[i], j = i; while (j > 0 && temp < a[j - 1 ]) { a[j] = a[j - 1 ]; j--; } a[j] = temp; } } int main () { int a[maxn] = { 3 ,5 ,1 ,7 ,9 ,0 ,3 ,5 }; insertsort (a, 8 ); for (int i = 0 ; i < 8 ; i++) { cout << a[i] << " " ; } cout << endl; }
5.3.冒泡排序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include <iostream> #include <algorithm> using namespace std;void bubblesort (int a[], int n) { for (int i = 1 ; i < n; i++) { for (int j = 0 ; j < n - i; j++) { if (a[j] > a[j + 1 ]) { swap (a[j], a[j + 1 ]); } } } } int main () { int a[8 ] = { 0 ,5 ,7 ,1 ,4 ,2 ,7 ,4 }; bubblesort (a, 8 ); for (int i = 0 ; i < 8 ; i++) { cout << a[i] << " " ; } cout << endl; }
5.4.快速排序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #include <iostream> #include <algorithm> using namespace std;int partition (int a[], int left, int right) { int temp = a[left]; while (left < right) { while (left < right && a[right] > temp) right--; a[left] = a[right]; while (left < right && a[left] <= temp) left++; a[right] = a[left]; } a[left] = temp; return left; } void quicksort (int a[], int left, int right) { if (left < right) { int pos = partition (a, left, right); quicksort (a, left, pos - 1 ); quicksort (a, pos + 1 , right); } } int main () { int a[8 ] = { 0 ,5 ,7 ,1 ,4 ,2 ,7 ,4 }; quicksort (a, 0 , 7 ); for (int i = 0 ; i < 8 ; i++) { cout << a[i] << " " ; } cout << endl; }
5.5.归并排序 5.5.1递归实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #include <iostream> #include <algorithm> #include <vector> using namespace std;const int maxn = 100 ;void merge (int a[], int l1, int r1, int l2, int r2) { int i = l1, j = l2; int temp[maxn], index = 0 ; while (i <= r1 && j <= r2) { if (a[i] <= a[j]) { temp[index++] = a[i++]; } else { temp[index++] = a[j++]; } } while (i <= r1) temp[index++] = a[i++]; while (j <= r2) temp[index++] = a[j++]; for (i = 0 ; i < index; i++) { a[l1 + i] = temp[i]; } } void mergesort (int a[], int left, int right) { if (left < right) { int mid = (left + right) / 2 ; mergesort (a, left, mid); mergesort (a, mid + 1 , right); merge (a, left, mid, mid + 1 , right); } } int main () { int a[maxn] = { 3 ,5 ,1 ,7 ,9 ,0 ,3 ,4 }; mergesort (a, 0 , 7 ); for (int i = 0 ; i < 8 ; i++) { cout << a[i] << " " ; } cout << endl; }
5.5.2非递归实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 #include <iostream> #include <algorithm> #include <vector> using namespace std;const int maxn = 100 ;void merge (int a[], int l1, int r1, int l2, int r2) { int i = l1, j = l2; int temp[maxn], index = 0 ; while (i <= r1 && j <= r2) { if (a[i] <= a[j]) { temp[index++] = a[i++]; } else { temp[index++] = a[j++]; } } while (i <= r1) temp[index++] = a[i++]; while (j <= r2) temp[index++] = a[j++]; for (i = 0 ; i < index; i++) { a[l1 + i] = temp[i]; } } void mergesort2 (int a[], int n) { for (int step = 2 ; step / 2 <= n; step *= 2 ) { for (int i = 0 ; i < n; i += step) { int mid = i + step / 2 - 1 ; if (mid + 1 < n) { merge (a, i, mid, mid + 1 , min (i + step - 1 , n)); } } } } int main () { int a[maxn] = { 3 ,5 ,1 ,7 ,9 ,0 ,3 ,4 }; mergesort2 (a, 7 ); for (int i = 0 ; i < 8 ; i++) { cout << a[i] << " " ; } cout << endl; }