非递归实现二叉树的前序,中序,后序遍历

               引言: 捷径是最长的路,偷来的巧,是致命的拙。若无递归,则尔多窘。

    1.前序遍历(迭代)

       解决思路: 使用栈模拟树的遍历. 顺序为根、左、右. 每个节点在入栈的时候便放入ret中,入栈表示访问根.因为树的遍历开始,拿的就是根.然后拿左子树中的根,右子树中的根...一种递归思想不知所言.

 vector<int> preorderTraversal(TreeNode* root) {
        stack<TreeNode*> s;
        vector<int> ret;
 
        while(!s.empty() || root)
        {
            if(root!=nullptr)
            {
               s.push(root);
               ret.push_back(root->val);
               root=root->left;
            }
            else
            {
               root=s.top();
               s.pop();
               if(root->right==nullptr)
                 root=nullptr;
               else       
                 root=root->right;
              
            }
        }

        return ret;
    }

  

               2.中序遍历(迭代)

                       解决思路: 使用栈模拟树的遍历,顺序为左、根、右.每个节点在出栈的时候放入ret.出栈表示访问左子树,因为树的遍历开始拿的是根,所以要先访问左子树,然后访问左子树的左子树,直到最左,然后是最左的根,最左的右,往上遍历..

vector<int> inorderTraversal(TreeNode* root) {
        stack<TreeNode*> s;
        vector<int> ret;
        while(!s.empty() || root)
        {
            while(root!=nullptr)
            {
                s.push(root);
                root=root->left;
            }

            root = s.top();
            s.pop();
            ret.push_back(root->val);
            if(root->right==nullptr)
            {
                root=nullptr;
            }
            else
            {
                root=root->right;
            }
        }

        return ret;
    }

  

               3.后序遍历(迭代)

      解决思路1: 用栈模拟树的遍历,顺序是左、右、根.每个节点出栈并且右子树已经走过才放入ret.要确保右子树访问过,需要实现一个标记记录走过的右子树.

 vector<int> postorderTraversal(TreeNode* root) {
        stack<TreeNode*> s;
        vector<int> ret;
        TreeNode* rp = nullptr;

        while(!s.empty()||root)
        {
            while(root)
            {
                s.push(root);
                root=root->left;
            }

            root = s.top();
            //结束的条件即右节点返回. 记录每次返回的右节点就知道根什么时候能输出了
            if(root->right==nullptr || rp==root->right)
            {
                  ret.push_back(root->val);
                  rp = root;
                  s.pop();
                  root=nullptr;
            }
            else
            {
                root = root->right;
            }

        }
        
        
        return ret;
    }

      解决思路2: 模拟栈实现树的遍历. 顺序是根、右、左. 对结果进行反转即为所得: 左、右、中

 vector<int> postorderTraversal(TreeNode* root) {
        stack<TreeNode*> s;
        vector<int> ret;
        while(!s.empty()||root)
        {
            if(root!=nullptr)
            {
                s.push(root);
                ret.push_back(root->val);
                root = root->right;
            }
            else
            {
                root = s.top();
                s.pop();
                if(root->left==nullptr)
                {
                    root = nullptr;
                }
                else
                {
                    root = root->left;
                }
            }
        }
        reverse(ret.begin(),ret.end());
        
        
        return ret;
    }

  

posted @ 2020-11-01 00:39  Duikerdd  阅读(164)  评论(0编辑  收藏  举报