二叉樹非遞迴遍歷的一點理解

2021-10-02 14:11:21 字數 1899 閱讀 1134

二叉樹是我們必須要了解的乙個資料結構,針對這個資料結構我們可以衍生出好多知識。

主要是有幾種遍歷方式,前序遍歷,中序遍歷,後續遍歷,層次遍歷。

下面我們根據這個圖來詳細的說一下這幾種非遞迴遍歷的思想與做法。

只有真正理解了,我們才是真的會了,遇到相似的問題我們就會迎刃而解。

上面的圖是我自己畫的,以下的幾種遍歷方式也都是圍繞這個圖展開的。

所以首先我們先要構建乙個上面的圖,整體構建的思路有點類似於完全二叉樹的構建,如果大家了解堆排序那麼理解這個問題其實並不難,對於完全二叉樹節點之間會有這樣的關係

如果根節點位置為i那麼左節點位置為2i+1右節點為2i+2。

如果節點位置為i根節點的位置為(i-1)/2

所以有了這個關係我們不難構建出乙個二叉樹。

前序遍歷的整體思想我們可以這樣理解,要遵循這樣乙個遍歷方式就是根左右。先輸出根節點,然後左節點,然後右節點。每個節點的遍歷都要遵循這種方式,因為棧的特點是先進後出,所以我們保證每次輸出的元素都是根節點然後先將右節點壓棧,在將左節點壓棧,這樣每次出棧都是先以左節點為主,符合我們根左右的模式。

中序遍歷的整體思想就是左根右的模式,如果二叉樹是一顆二叉查詢樹,那麼通過中序遍歷輸出的結果就是乙個有序的結果,因為二叉查詢樹的定義就是左節點比根節點小,右節點比根節點大,所以我們以左根右的模式輸出的話就是有序的。

以下**的思想是這樣我們首先輸出的第乙個元素肯定是以左節點為主的最後乙個葉子節點,所以我們以迴圈的方式將根節點的左節點一直壓棧,然後在出棧,出棧的時候判斷一下右節點是否為空,如果為空我們繼續出棧,如果不為空將右節點壓棧,右節點賦值給當前節點,繼續執行之前的步驟即可。

後續遍歷的整體思想就是左右根,這裡我寫了兩種方法,第一種是比較有技巧的,我們理解起來也不難,借助了兩個棧來實現,下面的比較清晰,我們也能比較快速的理解其實就是跟左右方式的逆序,換一句話說就是先序遍歷的左右子樹反過來,然後在逆序輸出就可以了。

這種方式就是我們常規的思路了。以左右根的方式來遍歷,所有我們最先輸出的一定是左節點,然後是右節點,最後是根節點。

輸出的條件就是左子樹和右子樹都為空,那這個節點就是葉子節點,還有一種不是葉子節點,我們的判斷是保留上一次出棧的記錄,如果上一次出棧的記錄是當前節點的左孩子或者右孩子我們依然出棧,按照這整個思路我們有了以下**。

層次遍歷比較簡單,借助佇列這種資料結構。

自己測試了一下,這裡只展示後續遍歷的執行結果。

後續遍歷的執行結果。

二叉樹的非遞迴遍歷,還有一點黑科技

二叉樹的前中後序遍歷,可以用遞迴秒解,看起來不值一提。但如果不允許採用遞迴,要怎麼實現呢?還是先來看看遞迴演算法的實現吧 def visit root if root is not null 1visit root.left 2visit root.right 3上面展示的 中有三個位置 1,2,3...

二叉樹遍歷(遞迴 非遞迴)

二叉樹以及對二叉樹的三種遍歷 先根,中根,後根 的遞迴遍歷演算法實現,以及先根遍歷的非遞迴實現。node public class node public node left public node right public object value 遍歷訪問操作介面 public inte ce ...

二叉樹非遞迴遍歷

二叉樹非遞迴遍歷的幾個要點 1 不管前序 中序還是後序,它們的遍歷路線 或者說是回溯路線,先沿左邊一直走到盡頭,然後回溯到某節點,並跳轉到該節點的右孩子 如果有的話 然後又沿著這個有孩子的左邊一直走到盡頭 都是一樣的。2 明確每次回溯的目的。比如,前序回溯的目的是為了訪問右子樹 中序回溯的目的是為了...