一、二叉樹程式設計概述
程式 =資料結構+演算法。更精確地說,任何程式的功能實現,從技術角度來說,通過選取合適的資料結構和高效的演算法即可做到。二叉樹是一種非線性資料結構,即每乙個元素都可能有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...