中序遍歷對BST很是重要,以前也講過了BST的基本操做。(東哥總結的是真的強)算法
給定一個正整數n,請你計算,存儲{1,2,3...n}這些值共有多少種不一樣的BST結構。
仍是那句老話,二叉樹算法的關鍵在於明確根節點須要作什麼。
假設給算法輸入5,也就是說用{1,2,3,4,5}這些數字去構造BST。
首先,這棵BST的根節點總共有幾種狀況?
顯然有5中,由於1-5均可以做爲BST的根節點對吧。而後咱們固定住一個根節點,而後再進行分析,這個時候有幾種不一樣的BST呢?
好比樹把3固定住,去分析其餘樹節點均可能的狀況。
根據BST的性質,根節點的左子樹都比根節點的值小,右子樹的值都比根節點的值大。因此若是固定3爲根節點,左子樹節點就是{1,2}的組合,右子樹就是{4,5}的組合。
左子樹的組合數和右子樹的組合數乘積就是3爲根時的BST個數。
上面講的是以3爲根的狀況,其餘節點也是同樣的。
[1,2]和[4,5]有幾種組合呢?
排列組合公式 2*2=4種,也就是說咱們的結果就是左右子樹組合的乘積。
使用遞歸函數函數
//閉區間[lo,hi]的數字能組成count(lo,hi)種BST int count(int lo,int hi);
根據這個函數的定義,結合剛纔的分析,能夠寫出代碼spa
//主函數 int numTrees(int n){ //計算閉區間[1,n]組成的BST的個數 return count(1,n); } //計算閉區間[lo,hi]組成的BST個數 int count(int lo,int hi){ //base case if(lo>hi){ return 1; } int res=0; for(int i=lo;i<=hi;i++){ //i的值做爲根節點root int left=count(lo,i-1); int right=count(i+1,hi); //左右子樹的組合數乘積是BST的總數 res+=left*right; } }