二叉树的前中后序遍历(非递归)
前序遍历一:
vector<int> preorderTraversal(TreeNode* root) { stack<TreeNode*> S; vector<int> v; TreeNode* rt = root; while(rt || S.size()){ while(rt){ S.push(rt->right); v.push_back(rt->val); rt=rt->left; } rt=S.top();S.pop(); } return v; }
前序遍历二:
vector<int> preorderTraversal(TreeNode* root) { vector<int> res; if(!root) return res; TreeNode* p = root; stack<TreeNode*> S; S.push(root); while(!S.empty()) { p = S.top(); S.pop(); res.push_back(p->val); if(p->right) S.push(p->right); if(p->left) S.push(p->left); } return res; }
中序遍历:
vector<int> inorderTraversal(TreeNode* root) { stack<TreeNode*> S; vector<int> v; TreeNode* rt = root; while(rt || S.size()){ while(rt){ S.push(rt); rt=rt->left; } rt=S.top();S.pop(); v.push_back(rt->val); rt=rt->right; } return v; }
后序遍历一:
vector<int> postorderTraversal(TreeNode* root) { stack<TreeNode*> S; vector<int> v; TreeNode* rt = root; while(rt || S.size()){ while(rt){ S.push(rt->left); v.push_back(rt->val); rt=rt->right; } rt=S.top();S.pop(); } reverse(v.begin(),v.end()); return v; }
后序遍历二:
vector<int> postorderTraversal(TreeNode* root) { vector<int> res; stack<TreeNode*> S; TreeNode *rt = root, *pre = NULL; while (rt || !S.empty()) { while (rt) {//走到最左边 S.push(rt); rt = rt->left; } rt = S.top(); if (rt->right && rt->right != pre)//右子树存在,未被访问 rt = rt->right; else { S.pop(); res.push_back(rt->val); pre = rt; //记录最近访问过的节点 rt = NULL; //回溯的重要步骤 } } return res; }
后序遍历三:
vector<int> postorderTraversal(TreeNode* root) { vector<int> res; stack<TreeNode*> S; TreeNode *rt = root; TreeNode *pre = NULL; if(rt == NULL) return res; S.push(root); while(!S.empty()) { rt = S.top(); if(!rt->left && !rt->right || (pre && (pre == rt->left || pre == rt->right))) { res.push_back(rt->val); S.pop(); pre = rt; } else { if(rt->right) S.push(rt->right); if(rt->left) S.push(rt->left); } } return res; }
后序遍历四:
vector<int> postorderTraversal(TreeNode* root) { vector<int> res; stack<TreeNode*> S; if(root) S.push(root); while(!S.empty()) { TreeNode *t = S.top(); S.pop(); if(t) { S.push(t); //在右节点之前重新插入该节点,以便在最后处理(访问值) S.push(nullptr); //nullptr跟随t插入,标识已经访问过,还没有被处理 if(t->right) S.push(t->right); if(t->left) S.push(t->left); } else { res.push_back(S.top()->val); S.pop(); } } return res; }