二叉樹先序 中序 後序遍歷的非遞迴實現

2021-07-03 08:33:06 字數 1935 閱讀 6214

分類: 資料結構

acm 2010-11-23 14:34

746人閱讀收藏 

舉報null

演算法struct

input

在網上看了一些用非遞迴實現先序中序後序遍歷二叉樹的**,都很混亂,while、if各種組合巢狀使用,邏輯十分不清晰,把我也搞懵了。想了大半天,寫了大半天,突然開了竅,實際上二叉樹的這三種遍歷在邏輯上是十分清晰的,所以才可以用遞迴實現的那麼簡潔。既然邏輯如此清晰,那麼用非遞迴實現也應該是清晰的。

自認為自己的**比網上搜到的那些都清晰得多,好理解得多。

稍微解釋一下:

先序遍歷。將根節點入棧,考察當前節點(即棧頂節點),先訪問當前節點,然後將其出棧(已經訪問過,不再需要保留),然後先將其右孩子入棧,再將其左孩子入棧(這個順序是為了讓左孩子位於右孩子上面,以便左孩子的訪問先於右孩子;當然如果某個孩子為空,就不用入棧了)。如果棧非空就重複上述過程直到棧空為止,結束演算法。

中序遍歷。將根節點入棧,考察當前節點(即棧頂節點),如果其左孩子未被訪問過(有標記),則將其左孩子入棧,否則訪問當前節點並將其出棧,再將右孩子入棧。如果棧非空就重複上述過程直到棧空為止,結束演算法。

後序遍歷。將根節點入棧,考察當前節點(即棧頂節點),如果其左孩子未被訪問過,則將其左孩子入棧,否則如果其右孩子未被訪問過,則將其右孩子入棧,如果都已經訪問過,則訪問其自身,並將其出棧。如果棧非空就重複上述過程直到棧空為止,結束演算法。

其實,這只不過是保證了先序中序後序三種遍歷的定義。對於先序,保證任意乙個節點先於其左右孩子被訪問,還要保證其左孩子先於右孩子被訪問。對於中序,保證任意乙個節點,其左孩子先於它被訪問,右孩子晚於它被訪問。對於後序,保證任意乙個節點的左孩子右孩子都先於它被訪問,其中左孩子先於右孩子被訪問。如是而已。

**裡應該體現得比較清楚。這裡不光給出了非遞迴版本,也給出了遞迴版本。

[cpp]view plain

copy

#include 

#include 

using

namespace

std;  

struct

treenode   

;  typedef

treenode *treeptr;  

treeptr createtree()  

else

return

root;  

}  void

preorderrecursion(treeptr p)  

cout;  preorderrecursion(p->left);  

preorderrecursion(p->right);  

}  void

inorderrecursion(treeptr p)  

inorderrecursion(p->left);  

cout;  inorderrecursion(p->right);  

}  void

postorderrecursion(treeptr p)  

postorderrecursion(p->left);  

postorderrecursion(p->right);  

cout;  }  

void

preordernorecursion(treeptr p)  

if(t.left != null)  

}  }  void

inordernorecursion(treeptr p)  

}  else

}  }  }  

void

postordernorecursion(treeptr p)  

}   

else

if(stk.top().flag == 1)  

}   

else

}  }  int

main()    

二叉樹的非遞迴遍歷(先序,中序,後序)

遍歷演算法 1 中序遍歷的遞迴演算法定義 若二叉樹非空,則依次執行如下操作 1 遍歷左子樹 2 訪問根結點 3 遍歷右子樹。2 先序遍歷的遞迴演算法定義 若二叉樹非空,則依次執行如下操作 1 訪問根結點 2 遍歷左子樹 3 遍歷右子樹。3 後序遍歷得遞迴演算法定義 若二叉樹非空,則依次執行如下操作 ...

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

二叉樹的非遞迴遍歷 先序遍歷,中序遍歷,後序遍歷 include include using namespace std typedef struct node binode,bitree 先序遞迴建立樹,這裡注意引數的型別,t的型別是 如果是 稍加改動就ok.void createtree bit...

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

演算法思想 先序 nlr的訪問順序,由於r節點,即右孩子的訪問需要通過根節點的指標來實現,所以,需要設乙個棧來儲存根節點。具體看 void preorder btree t else while 中序遍歷和先序遍歷幾乎一樣 void midorder btree t else 後序遍歷 lrn順序。...