本文主要总结先序,中序,后序的非递归,基本思路都是用stack进行
先序的非递归,两种写法,一种是注意加入左右孩子时判断是否为空,主要注意先加入右孩子保证左孩子先出来
void preOrderIter(TreeNode *root)
{
if (root == nullptr) return;
stack<TreeNode *> s;
s.push(root);
while (!s.empty()) {
TreeNode *nd = s.top();
ans.push_back(nd->val);
s.pop();
if (nd->right)
s.push(nd->right);
if (nd->left)
s.push(nd->left);
}
}
另一种写法,一直访问左孩子直到空访问右孩子
void preOrderIter2(TreeNode *root)
{
stack<TreeNode *> s;
while (root || !s.empty()) {
if (root) {
ans.push_back(root->val);
s.push(root);
root = root->left; //访问左子树
} else {
root = s.top(); //回溯至父亲结点
s.pop();
root = root->right; //访问右子树
}
}
}
中序遍历:
void inOrderIter(TreeNode *root)
{
stack<TreeNode *> s;
while (root != NULL || !s.empty()) {
if (root != NULL) {
s.push(root);
root = root->left;
}
else {
root = s.top();
ans.push_back(root->val);
s.pop();
root = root->right; //访问右子树
}
}
}
后序遍历:
void postOrderIter(TreeNode *root)
{
if (!root) return;
stack<TreeNode*> s;
s.push(root);
while (!s.empty()) {
TreeNode *curr = s.top();
ans.push(curr);
s.pop();
if (curr->left)
s.push(curr->left);
if (curr->right)
s.push(curr->right);
}
reverse(ans.begin(),ans.end());
}