非遞迴實現二叉樹中序遍歷 前序遍歷和後序遍歷

2021-10-07 13:28:34 字數 1245 閱讀 3935

遞迴方法下的二叉樹的中序遍歷比較簡單,大概過程就是func(root->left)?visit(root)?func(root->right),如果不使用遞迴的方法的話,就要用棧來模擬這個過程。

將乙個遞迴函式轉換成為非遞迴的解決方法,最重要的就是搞明白在遞迴過程中函式棧的呼叫過程。我們可以思考一下記憶體狀況:

每次函式執行,一路向左,只有當某棵左子樹完全訪問完才會訪問根節點,之後在對根節點的右子樹重複同樣的過程,因此我們可以這樣進行實現

1.當前結點是樹根?推入棧中?去找它的左孩子

2.重複1,直到乙個結點不是樹根,也就是該節點為空,這意味著進入該結點的結點(父結點)的左子樹完全訪問完成,那麼我們訪問這個結點,完成中序過程。

3.我們訪問完該結點的左子樹和該結點,那麼應該訪問該結點的右子樹,這也是同樣的過程,只要走到它的右子樹上即可,此時當前結點又成為了乙個樹根,重複1過程

**如下:

node* node = root;

stack> st;

while

(node!=

null

||!st.

empty()

)else

}

類似的,我們可以寫出前序的非遞迴:

node* node = root;

stack> st;

while

(node||

!st.

empty()

)else

}

後序遍歷需要判斷上次訪問的節點是左子樹還是右子樹,如果該節點的左子樹已被訪問過則置標記為left;若右子樹被訪問過,則置標記為right:

//定義列舉型別:tag

enum tag

;//自定義新的型別,把二叉樹節點和標記封裝在一起

typedef

struct

tagnode;

//後序遍歷

void

postorderwithoutrecursion2

(btnode* root)

tagnode = s.

top();

s.pop();

//左子樹被訪問過,則還需進入右子樹

if(tagnode.tag == tag::left)

else

//右子樹已被訪問過,則可訪問當前節點

} cout << endl;

}

二叉樹的前序中序遞迴,非遞迴遍歷

二叉樹的前序,中序 遞迴,非遞迴遍歷 例如 二叉樹 6 14 4 8 12 16 前序遍歷的結果為 10 6 4 8 14 12 16 思路 非遞迴方法 先壓入根節點10 同時輸出資料 10 然後判斷 10有左子樹沒有,如果有則繼續壓入6 輸出 6 判斷6有沒有左子樹,如果有壓入 4,輸出 4.判斷...

二叉樹的遍歷 前序非遞迴和中序非遞迴

詳情可以見文章二叉樹建立和遞迴遍歷 建立如圖的二叉樹 就可以建立好上圖的二叉樹 非遞迴遍歷的演算法如下 include include using namespace std typedef char datatype 二叉樹的左右鏈表示,也叫做二叉鍊錶表示 typedef struct node ...

二叉樹的非遞迴前序中序後序遍歷

做個筆記,方便日後查閱 全部是模板函式,c 語言 template void preorder node root,ostream os if st.empty os endl template void midorder node root,ostream os if st.empty os en...