赞
踩
之前写的二叉树的前中后序遍历的迭代方法,中序遍历与前序后序遍历的代码并不统一,无法像递归那样只是修改顺序,就可以完成,在看完代码随想录二叉树的统一迭代法的章节后,记录一下。
通过对入栈的节点进行标记,只有当标记出现时,才将该元素添加到输出数组中,否则就继续遍历下去。通过更改标记节点 和左右节点的入栈顺序,从而达到只需修改代码顺序,就能切换功能,实现代码统一的目的。
中序遍历:
class Solution { public: vector<int> inorderTraversal(TreeNode* root) { vector<int> result; stack<TreeNode*> st; if (root != NULL) st.push(root); while (!st.empty()) { TreeNode* node = st.top(); if (node != NULL) { st.pop(); // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中 if (node->right) st.push(node->right); // 添加右节点(空节点不入栈) st.push(node); // 添加中节点 st.push(NULL); // 中节点访问过,但是还没有处理,加入空节点做为标记。 if (node->left) st.push(node->left); // 添加左节点(空节点不入栈) } else { // 只有遇到空节点的时候,才将下一个节点放进结果集 st.pop(); // 将空节点弹出 node = st.top(); // 重新取出栈中元素 st.pop(); result.push_back(node->val); // 加入到结果集 } } return result; } };
前序遍历:
class Solution { public: vector<int> preorderTraversal(TreeNode* root) { vector<int> result; stack<TreeNode*> st; if (root != NULL) st.push(root); while (!st.empty()) { TreeNode* node = st.top(); if (node != NULL) { st.pop(); if (node->right) st.push(node->right); // 右 if (node->left) st.push(node->left); // 左 st.push(node); // 中 st.push(NULL); } else { st.pop(); node = st.top(); st.pop(); result.push_back(node->val); } } return result; } };
后序遍历:
class Solution { public: vector<int> postorderTraversal(TreeNode* root) { vector<int> result; stack<TreeNode*> st; if (root != NULL) st.push(root); while (!st.empty()) { TreeNode* node = st.top(); if (node != NULL) { st.pop(); st.push(node); // 中 st.push(NULL); if (node->right) st.push(node->right); // 右 if (node->left) st.push(node->left); // 左 } else { st.pop(); node = st.top(); st.pop(); result.push_back(node->val); } } return result; } };
这里源码参考了 代码随想录,可以发现,使用NULL来标记需要处理的节点,在遍历时,只需更改左右节点和中间节点的入栈顺序,就能实现不同的遍历顺序。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。