【leetcode】Binary Tree Preorder Traversal (middle)★

Given a binary tree, return the preorder traversal of its nodes' values.

For example:
Given binary tree {1,#,2,3},

   1
    
     2
    /
   3

return [1,2,3].

二叉树的先序遍历。递归算法太简单了,重点讨论一下非递归的。

我自己写的时候一直纠结于何时弹出结点。后来看了几个版本的,发现可以跳过这个部分。

贴上我最喜欢的版本,逻辑最清楚

//我最喜欢的版本 逻辑清晰
    vector<int> preorderTraversal3(TreeNode *root) 
    {
        if (root==NULL) return vector<int>();
        vector<int> result;
        stack<TreeNode *> treeStack;
        treeStack.push(root);
        while (!treeStack.empty()) 
        {
            TreeNode *temp = treeStack.top();
            result.push_back(temp->val);
            treeStack.pop();
            if (temp->right!=NULL)  //先压入右子树,后压入左子树,只有非空的时候压入,这样处理后的根据栈的后进先出,自然就是先处理左子树,再处理右子树了
                treeStack.push(temp->right);
            if (temp->left!=NULL) 
                treeStack.push(temp->left);
        }
        return result;
    }

很短的版本:

vector<int> preorderTraversal2(TreeNode *root)
    {
        vector<int> ans;
        vector<TreeNode *> v;
        TreeNode * p = root;
        while(p != NULL)
        {
            ans.push_back(p->val);
            if(p->right != NULL)
            {
                v.push_back(p->right);
            }
            p = p->left;
            if(p == NULL && !v.empty())
            {
                p = v.back();
                v.pop_back();
            }
        }
        return ans;
    }

我自己写的,很长很繁琐。不好。

vector<int> preorderTraversal(TreeNode *root) {
        vector<int> ans;
        if(root == NULL) return ans;
        vector<TreeNode *> v;
        v.push_back(root);
        while(!v.empty())
        {
            TreeNode * p = v.back();
            if(p == NULL) //前面的压入右子树的过程中会出现NULL
            {
                v.pop_back(); //把这个指针弹出
                if(!v.empty())
                {
                    p = v.back(); 
                    v.pop_back(); //把再上一个指针也弹出
                    v.push_back(p->right); //压入刚才被弹出指针的右子树
                }
            }
            else
            {
                ans.push_back(p->val); //先读取值
                if(p->left != NULL)
                {
                    v.push_back(p->left); //左子树不为空 压入左子树
                }
                else 
                {
                    v.pop_back(); //否则弹出该节点 并压入右子树
                    v.push_back(p->right);
                }
            }
        }
        return ans;
    }
原文地址:https://www.cnblogs.com/dplearning/p/4435996.html