尋找樹(shù)中兩個(gè)節(jié)點(diǎn)的最低公共祖先與遞歸函數(shù)

遞歸算法

遞歸算法通常有兩種路召,一種是自己直接遞歸,另一種是結(jié)合一個(gè)Helper類幫助遞歸晃择,但本質(zhì)上都可以擴(kuò)展為第二種遞歸蛆楞。

例如:尋找兩個(gè)節(jié)點(diǎn)的最低公共祖先就屬于結(jié)合一個(gè)Helper類輔組遞歸

在這個(gè)功能的實(shí)現(xiàn)中使用了findCommonParentNode()hasNodes()兩個(gè)方法。

findCommonParentNode()是主體類杯道,負(fù)責(zé)邏輯上的實(shí)現(xiàn):

  • 如果兩個(gè)節(jié)點(diǎn)不同時(shí)在左子樹(shù)或右子樹(shù)匪煌,則說(shuō)明當(dāng)前根節(jié)點(diǎn)即為最低公共父節(jié)點(diǎn);
  • 如果兩個(gè)節(jié)點(diǎn)同時(shí)在右子樹(shù)党巾,則進(jìn)一步搜索右子樹(shù)萎庭;
  • 如果兩個(gè)節(jié)點(diǎn)同時(shí)在左子樹(shù),則進(jìn)一步搜索左子樹(shù)齿拂。

hasNodes是輔助類驳规,負(fù)責(zé)具體業(yè)務(wù)的實(shí)現(xiàn):

  • 遍歷給定樹(shù)找到給定的兩個(gè)節(jié)點(diǎn)
    /**
     * find nodes in leftTree and rightTree respectively
     * if both leftTree and rightTree don't have given nodes, it means
     * the current root node is the common node, then return the root.
     * if given nodes are in leftTree or rightTree, then we find them
     * in leftTree or rightTree
     * @param node1
     * @param node2
     * @param root
     * @return
     */
    public BinaryNode findCommonParentNode(BinaryNode node1, BinaryNode node2, BinaryNode root) {
        if (root == null)
            return null;

        boolean inLeftSubTree = hasNodes(node1, node2, root.left);
        boolean inRightSubTree = hasNodes(node1, node2, root.right);
        // 如果既不在左子樹(shù)又不在右子樹(shù),則說(shuō)明當(dāng)前節(jié)點(diǎn)就是最低公共祖先
        if (!inLeftSubTree && !inRightSubTree)
            return root;
            
        // 如果在左子樹(shù)或者右子樹(shù)中署海,則進(jìn)一步搜索左子樹(shù)或右子樹(shù)
        if (inLeftSubTree)
            return findCommonParentNode(node1, node2, root.left);
        else
            return findCommonParentNode(node1, node2, root.right);
    }

    /**
     * This is a level-sequence Traverse to find node1 and node2 in the given tree
     * @param node1
     * @param node2
     * @param root
     * @return
     */
    private boolean hasNodes(BinaryNode node1, BinaryNode node2, BinaryNode root) {
        Queue<BinaryNode> queue = new LinkedList<>();
        queue.add(root);

        boolean hasNode1 = false;
        boolean hasNode2 = false;

        while (!queue.isEmpty()) {
            BinaryNode node = queue.remove();

            // mark node1 and node2
            if (node == node1)
                hasNode1 = true;
            else if (node == node2)
                hasNode2 = true;

            // given tree has node1 and node2
            if (hasNode1 && hasNode2)
                return true;

            if (node.left != null)
                queue.add(node.left);
            if (node.right != null)
                queue.add(node.right);
        }
        return false;
    }

直接遞歸的有基本的遍歷:

在直接遞歸中業(yè)務(wù)實(shí)現(xiàn)代碼不是那么明顯吗购,容易讓人暈頭轉(zhuǎn)向医男,但只要把握住了遞歸邏輯,實(shí)際上是可以套用第二種遞歸方法的模式的巩搏。

遞歸函數(shù)最終返回的值是又最里層返回值所決定的

preOrder()前序遍歷將主體類和輔助類合并在了一起

前序遍歷要求:

  • 首先訪問(wèn)根節(jié)點(diǎn)昨登;
  • 有左節(jié)點(diǎn)的時(shí)候訪問(wèn)左節(jié)點(diǎn)趾代;
  • 沒(méi)左節(jié)點(diǎn)了訪問(wèn)右節(jié)點(diǎn)贯底;
    public void preOrder(BinaryNode root) {
        if (root == null)
            return null;
        
        // 先訪問(wèn)當(dāng)前節(jié)點(diǎn)
        System.out.print(root.val); // 僅僅只是輸出值,但可以替換成更復(fù)雜的邏輯
        // 再訪問(wèn)左節(jié)點(diǎn)
        preOrder(root.left);
        // 再訪問(wèn)右節(jié)點(diǎn)
        preOrder(root.right);
    } 
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末撒强,一起剝皮案震驚了整個(gè)濱河市禽捆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌飘哨,老刑警劉巖胚想,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異芽隆,居然都是意外死亡浊服,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門胚吁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)牙躺,“玉大人,你說(shuō)我怎么就攤上這事腕扶∧蹩剑” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵半抱,是天一觀的道長(zhǎng)脓恕。 經(jīng)常有香客問(wèn)我,道長(zhǎng)窿侈,這世上最難降的妖魔是什么炼幔? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮史简,結(jié)果婚禮上乃秀,老公的妹妹穿的比我還像新娘。我一直安慰自己乘瓤,他們只是感情好环形,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著衙傀,像睡著了一般抬吟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上统抬,一...
    開(kāi)封第一講書(shū)人閱讀 51,287評(píng)論 1 301
  • 那天火本,我揣著相機(jī)與錄音危队,去河邊找鬼。 笑死钙畔,一個(gè)胖子當(dāng)著我的面吹牛茫陆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播擎析,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼簿盅,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了揍魂?” 一聲冷哼從身側(cè)響起桨醋,我...
    開(kāi)封第一講書(shū)人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎现斋,沒(méi)想到半個(gè)月后喜最,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡庄蹋,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年瞬内,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片限书。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡虫蝶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蔗包,到底是詐尸還是另有隱情秉扑,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布调限,位于F島的核電站舟陆,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏耻矮。R本人自食惡果不足惜秦躯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望裆装。 院中可真熱鬧踱承,春花似錦、人聲如沸哨免。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)琢唾。三九已至载荔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間采桃,已是汗流浹背懒熙。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工丘损, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人工扎。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓徘钥,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親肢娘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子呈础,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容