對大多數程序員來講,遞歸算法都不算陌生。甚至不少時候,使用遞歸算法解決一些簡單問題是基礎教材的起步課程。可是,當遞歸算法遇到稍微複雜的數據結構,如二叉搜索樹的時候。別說讓你直接寫出算法,就是把標準答案擺在你的面前讓你理解,咱們恐怕都會抓耳撓腮。若是你也有相似的困擾請不要灰心,由於包括我在內幾乎我遇到的每個碼農在這些方面都顯得束手無策。究其緣由,我認爲這實際上是認知心理的一種表現——咱們沒法勝任同時正向思考與反向記憶——大多數的時候,咱們能夠輕鬆應付函數的一層層遞進,卻很難記住每一層的返回值。終於我發現經過一種簡單而有效的圖形結構可讓咱們理解各種遞歸算法,下面進入正題。程序員
定義在一個標準的二叉搜索樹算法中包含一個方法以獲取小於某一個鍵值Key的最大節點對象:算法
/** * Node包含一個鍵值對<Key extends Comparable<Key>, Value> * 以及一棵左子樹和一棵右子樹Node left, right * * class Node { * private Key key; * private Value val; * private Node left, right; * } */ Node floor(Node n, Key key) { if (n == null) { return null; } int cmp = key.compareTo(n.key); if (cmp == 0) { return n; } else if (cmp < 0) { return floor(n.left, key); } else { Node r = floor(n.right, key); if (r != null) { return r; } else { return n; } } }
算法不復雜,對二叉搜索樹不太瞭解的能夠先去熟悉一下數據結構。但是想讀懂這幾行代碼確實令我頭疼,畢竟若是讀不懂就不可能記住更不可能在須要的時候本身寫出來。接下來就是見證奇蹟的時刻:數據結構
首先,任何一種遞歸算法都必然包含四種要素:輸入,輸出,遞歸條件和終止條件。floor方法含有兩個遞歸條件cmp<0和cmp>0以及三個終止條件n==null, cmp==0和r==null。函數
其次,咱們將要經過簡單的圖形來表明層層的遞歸順序,而且幫助咱們在達到終止條件的時候記錄返回值。若是在稿紙上繪製甚至還能夠更簡潔一些。spa
如下是一個完整的演示: Node(H) floor( Node(S), Key(J) )3d
跟着floor方法繪製遞歸圖你大概應該得到和我相似的結果:code
是否是感受瞬間思路清晰了!若是你也以爲這樣的方法對你有所幫助或者還有更好的建議不妨在留言中分享出來。對象