三种遍历方式的非递归写法
从网上看了大量的非递归写法,还有书上的,感觉写的复杂了。下面简化一下。
前序遍历非递归
stack<int>s;
while(!s.empty() || root) {
if(root) {
printf("%d", root->val);
s.push(root);
root = root->left;
} else {
root = s.top();s.pop();
root = root->right;
}
中序遍历非递归写法
和前序遍历只有输出位置不一样。
stack<int>s;
while(!s.empty() || root) {
if(root) {
s.push(root);
root = root->left;
} else {
root = s.top();s.pop();
printf("%d", root->val);
root = root->right;
}
后序遍历非递归写法:
两种算法,第一种增加一个变量判断是否是第一次出现在栈顶,如果是第二次,就可以输出了。
void postSearch(TreeNode *root) {
stack<pair<TreeNode*, bool> > s;
s.emplace(root, false);
while(!s.empty()) {
auto [t, vis] = s.top();s.pop();
if(t == NULL) continue;
if(vis) {ans.push_back(t->val);}
else {
s.emplace(t, true);
s.emplace(t->right, false);
s.emplace(t->left, false);
}
}
}
第二种,增加一个变量pre.记录上一个输出的节点
要注意向哪里走,如果根节点输出了就应该让root = NULL,否则最外层的循环跳不出来。
void postSearch(TreeNode *root) {
stack<TreeNode>s;
while(!s.empty() || root) {
if(root) {
s.push(root);
root = root->left;
} else {
root = s.top();s.pop();
if(!root->right || root->right == pre) {
printf("%d", root->val);
pre = root;
root = NULL;
} else {
s.push(root); //重新放入循环
root = root->right;
}
}
}