zoukankan      html  css  js  c++  java
  • 【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;
        }
  • 相关阅读:
    文件操作小练习
    阶段练习1
    copy小练习
    小练习
    str 小列题
    条款50:使用自定义的new以及delete的时机会
    条款49:了解new-handle行为
    简单的说一下:tarits技法就是一种模板元编程,起可以将本来处于运行期的事拉到编译期来做,增加了运行效率。 看以非模板元编程的例子,就是前面的那个例子:
    条款47:请使用traits class表示类型信息
    条款46:需要类型转换的时候请为模板定义非成员函数
  • 原文地址:https://www.cnblogs.com/dplearning/p/4435996.html
Copyright © 2011-2022 走看看