能遞迴實現的一般都可以用棧來實現,因此可以用棧來實現二叉樹的非遞迴遍歷。以下圖的二叉樹為例:
1、先序遍歷:首先把根結點入棧,然後根結點出棧(訪問結點),在出棧的同時將其右左孩子進棧,再把棧頂元素出棧(訪問結點),同時將其右左孩子入棧,如此反覆知道棧為空。
還有另外一種方法:
(1)將二叉樹的根結點作為當前結點;
(2)若當前結點非空,先訪問該結點,並將該結點進棧,再將其左孩子結點作為當前結點,重複步驟(2),直到當前結點為空;
(3)若棧非空,則棧頂結點出棧,並將當前結點的右孩子在哦為當前結點;
(4)重複步驟(2)(3),直到棧為空且當前結點為空。
void preorderunrec1(btree *root)
stacks;
btree *p;
p = root;
while (p != null && !s.empty())
if (!s.empty())}}
2、中序遍歷:
(1)將二叉樹的根結點作為當前結點;
(2)如果當前結點非空,則該結點進棧並將其左孩子作為當前結點,重複步驟(2)直到當前結點為空;
(3)若棧非空,將棧頂結點出棧並訪問,再將其右孩子作為當前結點;
(4)重複步驟(2)(3),直到棧為空且當前結點為空。
void midorderunrec(btree *root)
stacks;
btree *p;
p = root;
while (p != null || !s.empty())
if (!s.empty())
}}
3、後序遍歷:
後續遍歷的非遞迴實現可以仿照先序遍歷的第一種實現方法,和先序遍歷不同的是,後序遍歷不應該在出棧時才右左孩子進棧,而是應該在根父結點進棧的同時就把右左孩子入棧。在父結點出棧的時候,需要判斷左右孩子是否已經遍歷過,如果遍歷過了才能遍歷父結點。因此需要增加乙個標誌位來判斷右左孩子是否遍歷過,定義乙個新的結構體
typedef struct streenode
*pstree;
其中flag=0表示右左孩子沒有遍歷過,flag=2表示右左孩子已經遍歷完。
void postorderunrec(btree *root)
else
p->flag++;
//如果左孩子存在,則進棧並將標誌位加1
if (p->treenode->lchild)
p->flag++;
} }}
二叉樹遍歷(遞迴 非遞迴)
二叉樹以及對二叉樹的三種遍歷 先根,中根,後根 的遞迴遍歷演算法實現,以及先根遍歷的非遞迴實現。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次函式呼叫,這將極大地增加程式執行時間。這時,應該採取非遞迴便利二叉...