简体   繁体   English

二叉树的前序遍历

[英]Preorder traversal of binary tree

Ques - Given the root of a binary tree, return the preorder traversal of its nodes' values.问题 - 给定二叉树的根,返回其节点值的前序遍历。 Link Here 链接在这里

I am solving this question by recursion approach.我正在通过递归方法解决这个问题。 Given below is my code下面给出的是我的代码

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> ans;
        if(root)
        {
            ans.push_back( root -> val);
            preorderTraversal(root ->left);
            preorderTraversal(root ->right);
        }
        return ans;
    }
};

All the test cases are passed except one ie [1,null,2,3] .除了[1,null,2,3]之外的所有测试用例都通过了。 But when I declare vector<int> ans before vector<int> preorderTraversal(TreeNode* root) the test case gives correct output. I want to know why this happens.但是当我在vector<int> preorderTraversal(TreeNode* root)之前声明vector<int> ans时,测试用例给出了正确的 output。我想知道为什么会这样。

The ans variable is not shared among function calls, and you discard the result from the recursions, so you can add at most one element to the result. ans变量在 function 调用之间不共享,并且您丢弃递归的结果,因此您最多可以向结果添加一个元素。

Delegating to a helper function is a common solution that avoids copying and manual state management:委托给 helper function 是一种常见的解决方案,可以避免复制和手动 state 管理:

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> ans;
        traverse(root, ans);
        return ans;
    }
private:
    void traverse(const TreeNode* root, vector<int>& ans) const
    {
        if(root)
        {
            ans.push_back(root->val);
            traverse(root->left, ans);
            traverse(root->right, ans);
        }
    }
};

The problem is that you ignore the return values from the recursive calls to preorderTraversal .问题是您忽略了对preorderTraversal的递归调用的返回值。 Therefore your method will ever return maximum 1 value - the value of the root node.因此,您的方法将永远返回最大值 1 - root的值。

A simple solution for your current code would be to store the result of the resursive call in a variable and append the elements to ans :当前代码的一个简单解决方案是将递归调用的结果存储在一个变量中,并将 append 元素存储到ans中:

ans.push_back( root -> val);
auto l = preorderTraversal(root ->left);
ans.insert(ans.end(), l.begin(), l.end());
auto r = preorderTraversal(root ->right);
ans.insert(ans.end(), r.begin(), r.end());

This is not so efficient since the vectors from the recuresive calls are effectivly copied.这不是很有效,因为来自递归调用的向量被有效地复制了。

A more efficient approach would be to pass the result vector by reference to preorderTraversal (it should be created empty before calling it for the root).一种更有效的方法是通过引用preorderTraversal传递结果vector (它应该在为根调用它之前创建为空)。 Then preorderTraversal can add elements (including recursivly) to this result vector .然后preorderTraversal可以向这个结果vector添加元素(包括递归地)。

An alternative for passing the result by reference is storing it in a member variable of the class, as shown in the other answer.通过引用传递结果的另一种方法是将其存储在 class 的成员变量中,如另一个答案所示。

vector<int> ans; is a local variable that is destroyed after call to preorderTraversal .是调用preorderTraversal后销毁的局部变量。 Apart from that, you are ignoring return values of your recursive calls.除此之外,您将忽略递归调用的返回值。 I think you want to keep your ans as a class field and populate it with recursive calls:我认为您想将ans保留为 class 字段并用递归调用填充它:

class Solution {
public:
    void preorderTraversal(TreeNode* root) {
        if(root)
        {
            _ans.push_back( root -> val);
            preorderTraversal(root ->left);
            preorderTraversal(root ->right);
        }
    }
private:
    std::vector<int> _ans;
};

Then of course you would need some accessors, a way to clear the results, etc. But I guess this is not the scope of your question.那么你当然需要一些访问器,一种清除结果的方法等等。但我想这不是你问题中的 scope。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM