中序遍历使用栈遍历的话,会遇到访问节点(遍历节点)和处理节点(将元素放进结果集)不一致的情况。使得和前序遍历的代码逻辑不统一。
为了代码实现的统一性,把访问的节点放入栈时,我们可以同时把要处理的节点也放入栈中,只是要紧接着放入一个空指针作为标记。
迭代法中序遍历
中序遍历代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| 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; } };
|
可以看出我们将访问的节点直接加入到栈中,但如果是处理的节点则后面放入一个空节点, 这样只有空节点弹出的时候,才将下一个节点放进结果集。
迭代法前序遍历
迭代法前序遍历代码如下: (和中序遍历相比仅仅改变了两行代码的顺序)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| 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; } };
|
迭代法后序遍历
后续遍历代码如下: (和中序遍历相比仅仅改变了两行代码的顺序)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| 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; } };
|