一、先序非递归
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res; //保存遍历结果
if(!root) return res;
stack<TreeNode*> st;
TreeNode* p = root;
while(p||!st.empty())
{
while(p!=NULL)
{
res.push_back(p->val);
st.push(p);
p = p->left;
}
if(!st.empty())
{
p = st.top();
st.pop();
p = p->right;
}
}
return res;
}
二、中序非递归
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
if(!root)return res;
stack<TreeNode*> st;
TreeNode* p = root;
while(p!=NULL||!st.empty())
{
while(p!=NULL)
{
st.push(p);
p = p->left;
}
if(!st.empty())
{
p = st.top();
st.pop();
res.push_back(p->val);
p = p->right;
}
}
return res;
}
三、后序非递归
我们思考一下前序遍历和后序遍历之间的关系:
前序遍历顺序为:根 -> 左 -> 右
后序遍历顺序为:左 -> 右 -> 根
如果: 我们将遍历的顺序由从左到右修改为从右到左
那么结果链表就变为了:根 -> 右 -> 左
再整个进行一次反转
那么结果链表就变为了:左 -> 右 -> 根
这刚好是后序遍历的顺序
vector<int> postorderTraversal(TreeNode* root) {
vector<int> v;
if(!root)return v;
stack<TreeNode*> st;
TreeNode* p = root;
while(p||!st.empty())
{
while(p!=NULL)
{
v.push_back(p->val);
st.push(p);
p = p->right;//将遍历的顺序由从左到右修改为从右到左
}
if(!st.empty())
{
p = st.top();
st.pop();
p = p->left;
}
}
reverse(v.begin(),v.end());//最后进行一次反转
return v;
}
这比双栈的方法更加容易记忆,使得前中后非递归遍历代码统一了起来