二叉树的所有遍历非递归实现
二叉树前序、中序、后序、层序遍历的非递归实现。
前序遍历:
LeetCode链接:https://leetcode-cn.com/problems/binary-tree-preorder-traversal/
实现思路:
使用栈来模拟递归遍历操作。注意子节点的入栈顺序是 先右后左 ,因为栈后进先出(LIFO)的特性,左子节点将晚于右子节点被取出,这正符合了前序遍历 " 根->左->右 "的遍历顺序。
代码:
1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 * }; 11 */ 12 class Solution { 13 public: 14 vector<int> preorderTraversal(TreeNode* root) { 15 if(!root) return {}; //空树直接返回空的数组 16 vector<int> result; //用于存储遍历结果的向量 17 stack<TreeNode*> stk; //存储树节点指针变量的栈 18 stk.push(root); //将根节点压入栈中 19 20 while( !stk.empty() ) { //当栈为空时,退出循环 21 TreeNode* node = stk.top(); //使用临时变量保存栈顶结点 22 stk.pop(); //将栈顶节点弹出栈 23 result.emplace_back(node->val); //将节点的值插入到结果向量中 24 if(node->right) stk.push(node->right); //右子树非空,则压入栈中 25 if(node->left) stk.push(node->left); //左子树非空,则压入栈中 26 } 27 28 return ans; 29 } 30 };
后序遍历:
LeetCode链接:https://leetcode-cn.com/problems/binary-tree-postorder-traversal/
实现思路:
使用栈来模拟递归操作,同前序遍历的操作十分类似,只需将入栈顺序改为 根结点->左子节点->右子节点 即可,与前序遍历的 “根->左->右 ”恰好相反。在最后,当所有节点都遍历完成后,只需将保存遍历结果的vector反转即可得到后序遍历序列。以下代码,使用了algorithm头文件中的reverse()方法来反转保存遍历结果的vector。
代码:
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: vector<int> postorderTraversal(TreeNode* root) { if(!root) return {}; stack<TreeNode*> stk; vector<int> result; stk.push(root); while(!stk.empty()) { TreeNode* node = stk.top(); stk.pop(); result.emplace_back(node->val); if(node->left) { stk.push(node->left); } if(node->right) { stk.push(node->right); } } reverse(result.begin(),result.end()); return result; } };
中序遍历:
LeetCode链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal/
实现思路:
中序遍历同样使用栈来模拟递归操作。但与前序遍历以及后序遍历相比,中序遍历的结点入栈、出栈顺序有很大的不同,请看下方的代码实现。
代码:
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: vector<int> inorderTraversal(TreeNode* root) { if(!root) return {}; vector<int> result; stack<TreeNode*> stk; while(root || !stk.empty()) { while(root) { stk.push(root); root = root->left; } if(!stk.empty()) { TreeNode* node = stk.top(); stk.pop(); result.emplace_back(node->val); root = node->right; } } return result; } };
层序遍历:
LeetCode链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal/
实现思路:
使用队列来实现层序遍历操作。
/**
* Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: vector<vector<int>> levelOrder(TreeNode* root) { if(!root) return{}; vector< vector<int> > result; queue<TreeNode*> que; que.push(root); while(!que.empty()) { int queSize = que.size(); vector<int> temp; for(int i = 0; i < queSize; i++) { TreeNode* node = que.front(); que.pop(); temp.emplace_back(node->val); if(node->left) que.push(node->left); if(node->right) que.push(node->right); } result.emplace_back(temp); } return result; } };