1、前序遍歷node
分析:post
一、前序遍歷是中左右,所以利用棧,記錄棧頂根結點的同時,先壓右子樹,後壓左子樹,從而先遍歷左子樹。spa
二、每次彈出的棧頂結點符合前序遍歷的順序,所以可直接記錄。blog
三、注意:因爲壓入棧的是樹的結點,因此棧內數據類型爲Node*。get
struct Node{ int val; Node *left, *right; }; vector<int> get_preorder(Node *root){ vector<int> preorder; stack<Node*> st; st.push(root); while(!st.empty()){ Node* top = st.top(); st.pop(); preorder.push_back(top -> val); st.push(top -> right); st.push(top -> left); } return preorder; }
2、中序遍歷class
分析:遍歷
一、中序遍歷是左中右,對於一棵樹,利用棧,應當先壓入右子樹的根結點,再壓入根結點的值,再壓入左子樹的根結點。數據類型
二、如此操做,當棧頂元素是數字的時候進行記錄,所以寫一個結構體Stack_Element判斷當前壓入棧的是結點or結點的值。數據
struct Node{ int val; Node *left, *right; }; struct Stack_Element{ Node *node; int val; bool isNode; Stack_Element(Node *_node, int _val, bool _isNode):node(_node), val(_val), isNode(_isNode){} }; vector<int> get_inorder(Node *root){ vector<int> inorder; stack<Stack_Element> st; st.push(Stack_Element(root, -1, true));//因爲該棧中元素爲結點,所以他的值爲多少並不重要,因此此處設爲-1便可 while(!st.empty()){ Stack_Element top = st.top(); st.pop(); if(top.isNode){ if(top.node == NULL) continue; st.push(Stack_Element(top.node -> right, -1, true)); st.push(Stack_Element(NULL, top.node -> val, false)); st.push(Stack_Element(top.node -> left, -1, true)); } else{ inorder.push_back(top.val); } } return inorder; }
3、後序遍歷top
分析:
一、與中序遍歷同樣要考慮壓入棧的元素是結點or結點的值。
二、惟一的區別是遍歷順序,所以將中序遍歷的代碼(20~22行)稍做改動便可。
struct Node{ int val; Node *left, *right; }; struct Stack_Element{ Node *node; int val; bool isNode; Stack_Element(Node *_node, int _val, bool _isNode):node(_node), val(_val), isNode(_isNode){} }; vector<int> get_postorder(Node *root){ vector<int> postorder; stack<Stack_Element> st; st.push(Stack_Element(root, -1, true));//因爲該棧中元素爲結點,所以他的值爲多少並不重要,因此此處設爲-1便可 while(!st.empty()){ Stack_Element top = st.top(); st.pop(); if(top.isNode){ if(top.node == NULL) continue; st.push(Stack_Element(NULL, top.node -> val, false)); st.push(Stack_Element(top.node -> right, -1, true)); st.push(Stack_Element(top.node -> left, -1, true)); } else{ postorder.push_back(top.val); } } return postorder; }