有關二叉樹的遍歷問題非遞迴

2021-08-05 19:21:52 字數 1535 閱讀 4490

最近在刷題,經常會遇到一些樹的遍歷問題。在之前也寫過部落格詳細講解二叉樹遍歷問題的遞迴實現,可以戳有關二叉樹的遍歷問題去瞅瞅。這篇部落格主要想整理一下非遞迴的實現及遍歷思想。

如上圖這是乙個二叉樹。以前序為例,如果我們想直接去遍歷結點,肯定是不行的。首先肯定需要乙個大迴圈,然後一直找左孩子,直到左孩子不存在,然後需要跳出迴圈,去找沒有左孩子的當前根結點是否有右孩子。在這裡我們需要借助乙個資料結構—棧,我們先將遍歷的結點都放在棧裡,如果沒有左孩子就將當前結點pop掉,去找右孩子,然後接著尋找右孩子的左孩子……依次類推,直到遍歷完整個樹。

整個過程如上圖所示。**如下。

void prevordernonr()

node* tmp = s.top();

s.pop();

cur = tmp->_right;

}cout

<< endl;

}

前序遍歷規則是根-左-右,所以我們在找最左孩子的時候,就對資料進行了訪問。如果是中序遍歷,那麼需要先找到最左孩子,然後在進行訪問。中序遍歷的思路和上面差不多就不多贅餘了。**如下。

void inordernonr()

node* tmp = s.top();

cout

<< tmp->_data << " ";

s.pop();

cur = tmp->_right;

}cout

<< endl;

}

下來要說說後序遍歷。後序遍歷的情況比較特殊。

以上圖的二叉樹為例,我們進行左-右-根遍歷的時候,最左孩子是2,但2並不是我們要找的結點,第乙個訪問的結點是3。所以找到當前結點的最左結點後,如果當前結點沒有右孩子或者說它自己就是上個結點的右孩子那麼就訪問,其他情況,就是左孩子找完了,需要找右孩子了。**如下。

void postordernonr()

node* tmp = s.top();

if (tmp->_right == null || tmp->_right == prev)

else

cur = tmp->_right;

}cout

<< endl;

}

總結一下,二叉樹的遍歷問題,最常見的是遞迴。如果要用到非遞迴,那麼需要考慮的就是如何將這些問題一點點細化。比如說後序遍歷的時候,我什麼時候選擇列印結點,我如何判斷這個結點是不是我要找符合條件的結點,該借助怎樣的資料結構可以使整個結構變得清楚。

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

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

二叉樹非遞迴遍歷

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

非遞迴遍歷二叉樹

中序遞迴遍歷 void inordertrvdigui node pnode 然而,當樹的深度很大 比如16 時 假設為滿二叉樹 樹的節點數為 2 0 2 1 2 2 2 15 2 16 65536,遍歷整個二叉樹意味著有65536次函式呼叫,這將極大地增加程式執行時間。這時,應該採取非遞迴便利二叉...