1.二叉樹的非遞歸中序遍歷算法
二叉樹的中序遍歷方法是:左中右,因此一開始會順着根節點的左孩子一直往下(這點和先序遍歷一樣,這也是二者前面部分代碼很相似的原因),到最后一個左孩子時嘗試把它的右孩子塞進棧內,然后順着它的的左孩子而下,直到不能訪問為止。利用的棧FILO的特性,對每個節點都進行順左孩子而下即可。
上代碼:
1 void inOrder(TreeNode* root,vector<int>& inOrder) 2 { 3 stack<TreeNode*>st; 4 TreeNode* p = root; 5 while (p != nullptr || !st.empty()) 6 { 7 while (p != nullptr) 8 { 9 st.push(p); 10 p = p->left; 11 } 12 if (!st.empty()) 13 { 14 auto top = st.top(); 15 inOrder.push_back(top->val); 16 st.pop(); 17 p = top->left; 18 } 19 } 20 }
2。二叉樹的層次遍歷
思路:即每層遍歷,利用隊列FIFO特性,每當遍歷每層第一個元素時把它的子節點插入隊列,那么它也會時下一層第一個遍歷的。
int levelOrder(Node* root,vector<int>vecLevel) { if(root!=nullptr) { queue<Node*> q; q.push(root); while(!q.empty()) { auto front = q.front(); vecLevel.push_back(front); q.pop(); if(front->left!=nullptr) q.push(front->left); if(front->right!=nullptr) q.push(front->right); } } } }
3.二叉樹的先序遍歷
思路:二叉樹的先序遍歷即根→左→右,那么遍歷時會沿着根節點的左孩子而下直到最底層的左孩子,然后立即訪問當前最底層左孩子的右子樹,當訪問完,即返回上一層的左孩子節點,然后訪問其右子樹。
1 vector<int> preorderTraversal(TreeNode* root) { 2 vector<int>vec; 3 TreeNode* p = root; 4 stack<TreeNode*>st; 5 while(p!=nullptr || !st.empty()) 6 { 7 while(p!=nullptr) 8 { 9 st.push(p); 10 vec.push_back(p->val); 11 p=p->left; 12 } 13 if(!st.empty()) 14 { 15 p = st.top(); 16 st.pop(); 17 p = p->right; 18 } 19 } 20 return vec; 21 }
可以很明顯看出先序與中序遍歷幾乎一樣,但是實際上前者是在指針迭代時訪問結點值,后者是在棧頂訪問結點值。
具體實現可以參考這篇文章:https://www.jianshu.com/p/49c8cfd07410,當然我的思(dai)路(ma)也是從這里獲(chao)取(xi)的(🐶保命)