遞歸的思想就是,將大問題分解為小問題來求解,然后再將小問題分解為小小問題。這樣一層一層地分解,直到問題的數據規模被分解得足夠小,不用繼續遞歸分解為止。
如果我們把這個一層一層的分解過程畫成圖,它其實就是一棵樹。我們給這棵樹起一個名字,叫作遞歸樹。我這里畫了一棵斐波那契數列的遞歸樹,你可以看看。節點里的數字表示數據的規模,一個節點的求解可以分解為左右子節點兩個問題的求解。
舉個例子歸並排序,就是將數據規模一分為二
分析斐波那契
int f(int n) { if (n == 1) return 1; if (n == 2) return 2; return f(n-1) + f(n-2); }
分析全排列---“如何把 n 個數據的所有排列都找出來”
1, 2, 3 1, 3, 2 2, 1, 3 2, 3, 1 3, 1, 2 3, 2, 1
遞推公式
假設數組中存儲的是1,2, 3...n。
f(1,2,...n) = {最后一位是1, f(n-1)} + {最后一位是2, f(n-1)} +...+{最后一位是n, f(n-1)}。
代碼實現
// 調用方式: // int[]a = a={1, 2, 3, 4}; printPermutations(a, 4, 4); // k表示要處理的子數組的數據個數 public void printPermutations(int[] data, int n, int k) { if (k == 1) { for (int i = 0; i < n; ++i) { System.out.print(data[i] + " "); } System.out.println(); } for (int i = 0; i < k; ++i) { int tmp = data[i]; data[i] = data[k-1]; data[k-1] = tmp; printPermutations(data, n, k - 1); tmp = data[i]; data[i] = data[k-1]; data[k-1] = tmp; } }
、
參考王爭老師《數據結構與算法》