• (★★★)二叉树非递归遍历 (统一的解决思路)


    转载:【刷题】二叉树非递归遍历

    stack<Node*> st;
    
    
    void preOrder(Node* root) {
        Node *cur = root;
        while (cur || !st.empty()) {
            while (cur) {
                //访问、入栈、转向左孩子
                pre.push_back(cur->data);
                st.push(cur);
                cur = cur->lchild;
    
            }
    
            if (!st.empty()) {
                //出栈、转向右孩子
                cur = st.top();
                st.pop();
                cur = cur->rchild;
            }
        }
    }
    
    void inOrder(Node* root) {
        Node *cur = root;
        while (cur || !st.empty()) {
            while (cur) {
                //入栈、转向左孩子
                st.push(cur);
                cur = cur->lchild;
            }
    
            if (!st.empty()) {
                //出栈、访问、转向右孩子
                cur = st.top();
                st.pop();
                in.push_back(cur->data);
                cur = cur->rchild;
            }
        }
    }
    
    void postOrder(Node* root) {
        Node *cur = root, *pre = NULL;//pre指向上一个被访问过的节点
        while (cur || !st.empty()) {
            while (cur) {
                //入栈、转向左孩子
                st.push(cur);
                cur = cur->lchild;
            }
    
            if (!st.empty()) {
                //有条件的出栈,
                cur = st.top();
                // 如果已经访问了右子树,则可以访问根节点;否则转向,先去访问右子树
    
                if (cur->rchild == NULL || cur->rchild == pre) {
                    st.pop();
                    post.push_back(cur->data);
                    pre = cur;
                    cur = NULL;// 表示不需要转向,继续弹栈
    
                }
                else {
                    //转向
                    cur = cur->rchild;
                }
            }
        }
    }

    下面这种写法和笔记中的是统一的

    https://blog.csdn.net/u013161323/article/details/53925313

    void PostOrder(TreeNode *root) {
        TreeNode *p = root, *r = NULL;
        stack<TreeNode*> s;
        while (p || !s.empty()) {
            if (p) {//走到最左边
                s.push(p);
                p = p->left;
            }
            else {
                p = s.top();
                if (p->right && p->right != r)//右子树存在,未被访问
                    p = p->right;
                else {
                    s.pop();
                    visit(p->val);
                    r = p;//记录最近访问过的节点
                    p = NULL;//节点访问完后,重置p指针
                }
            }//else
        }//while
    }
  • 相关阅读:
    马云演讲:给自己一个梦想,给自己一个承诺,给自己一个坚持!
    转:如何成为一个伟大的开发者
    数据挖掘之七种常用的方法
    windows命令行
    100万亿意味着什么?
    ubuntu环境配置
    Ubuntu runlevel修改
    Ubuntu 用户及组管理
    Git学习笔记
    Git详解之三 Git分支
  • 原文地址:https://www.cnblogs.com/fuqia/p/9904581.html
Copyright © 2020-2023  润新知