二叉樹漫遊 遞迴技術

2022-01-13 17:18:06 字數 2047 閱讀 2570

一、二叉樹程式設計概述

程式 =資料結構+演算法。更精確地說,任何程式的功能實現,從技術角度來說,通過選取合適的資料結構和高效的演算法即可做到。二叉樹是一種非線性資料結構,即每乙個元素都可能有0個,1個,或2個後繼結點;這使得二叉樹程式設計比線性表程式設計增加了一些難度;另一方面,由於二叉樹具有天然的遞迴特性,要掌握二叉樹程式設計技術,須懂得如何用遞迴來思考問題以及熟練掌握遞迴程式的編寫,這對初學者來說,無疑是一道必須跨越的門檻。

二、遞迴技術概述

遞迴技術並不神秘。從方法層面上看,遞迴技術通過使用相同的方法求解比原問題規模更小的子問題,並合併子問題的解而實現;遞迴與分治是緊密關聯的;從技術手段上看,遞迴通過相同的函式呼叫來實現。即有p(n)= p(p(i),p(j), …, p(s),g(1))。

要寫出遞迴程式,其實也並不困難,有三點技巧:a.分析和找出遞迴的部分; b.確定遞迴呼叫的引數形式; c.確定遞迴結束條件。掌握這些技巧,甚至不用對遞迴機制作過多了解,就能寫出優雅的遞迴**。在後面的示例中,會逐漸給出一些相關的方法和技巧。

三、二叉樹的遞迴求解技術

二叉樹的遞迴求解通常可以歸納為以下步驟:

s1: 對根結點求解;

s2: 遞迴求解左子樹;

s3: 遞迴求解右子樹;

s4 : 合併根結點、左子樹、右子樹的解,進而得到原問題的解。

聰明的讀者馬上意識到,上述步驟與二叉樹的先序遍歷非常類似。針對具體的問題,s1,s2, s3 的順序可能有所變化。

a.  分析和找出遞迴的部分:

很顯然,二叉樹根結點的左子樹和右子樹都是一棵二叉樹,因此,可以用相同的策略求解左右子樹;這就是可以遞迴的部分;

b.   確定遞迴呼叫的引數形式:

這一點也比較明顯,即將二叉樹的根結點作為呼叫引數。根據問題需要,可能會增加一些其它的引數,用於標示當前遍歷的深度,要返回的列表等。

c.  確定遞迴條件。通常,根據應用將根結點需要滿足的條件作為遞迴結束條件。

這裡有乙個小技巧:你可以先對a/a(b,)/a(,b)/a(b,c)這幾種基本的二叉樹結構進行分析,以掌握遞迴程式的行為和機制。

四、示例

(1)二叉樹的先序、中序、後序遞迴遍歷。這個是最基本的,請讀者自行查閱相關書籍弄懂;

(2)求二叉樹的總結點數目。

a.  分析和找出遞迴的部分:很顯然,二叉樹的總結點數目 =1 + 左子樹的總結點數目 +右子樹的總結點數目。 1表示根結點。

b.  遞迴呼叫的引數: 二叉樹的根結點。

c.  遞迴結束條件: 根結點為空。 

現在,就可以開始寫遞迴程式了。先寫遞迴結束時的情況,再寫繼續遞迴的情況。熟練掌握遞迴程式的編寫不是一蹴而就的,多練習就習慣了。

publicint size(treenode root) 

else 

}

(3)將二叉樹所有結點的左右子樹交換

初看起來,像是很困難;然而運用遞迴的思維,很容易就能想到:如果根結點不為空,則交換根結點的左右子樹;遞迴求解左子樹;遞迴求解右子樹。於是,可以寫出遞迴程式:

publicvoid swaptree(treenode root)

}(4)

求二叉樹的最長路徑(如果有多條,輸出其中一條)

這個問題咋看起來,沒發現明顯可以遞迴的地方。這時,就需要仔細地分析。首先,二叉樹的最長路徑必定包括非空根結點;其次,最長路徑必定在葉子結點處到達;那麼,二叉樹的最長路徑與其左右子樹的最長路徑有什麼關聯呢?可以很容易想到:二叉樹的最長路徑

=非空根結點

longestpath(root):

if(root != null)

else

else

}}

由於二叉樹的遞迴求解通常非常簡潔,且執行效率也在可接受範圍內,因此,有人甚至建議:二叉樹的問題求解,首選遞迴技術。本文從方法層面上討論了如何編寫二叉樹的遞迴程式,這些方法和技巧使得,即使對遞迴的機制不甚了解,也可以寫出非常優雅的遞迴**。

二叉樹遞迴

我們來看一下二分搜尋樹的釋放,這就是乙個典型的遞迴問題 function destroy node 這個遞迴包括兩個部分,乙個是遞迴終止條件,乙個是遞迴的執行。我們知道遞迴是不斷地將當前函式壓入函式棧,如果沒有if node null return這個終止條件,當函式棧被壓滿之後就會發生棧溢位 棧的...

遞迴二叉樹

1 基本概念 1 節點 結點包含資料和指向其它節點的指標。2 根節點 樹第乙個結點稱為根節點。3 結點的度 結點擁有的子節點個數。4 葉節點 沒有子節點的節點 度為0 5 父子節點 乙個節點father指向另乙個節點child,則child為孩子節點,father為父親節點。6 兄弟節點 具有相同父...

二叉樹 遞迴

完全二叉樹 只有最後一層不滿,其餘節點都有兩個孩子,並且最後一層的節點從左向右排列,如下圖 擴充二叉樹 每個實節點都有兩個孩子,如圖 類似dfs cout data preorder recursion bt leftchild preorder recursion bt rightchild vo...