想知道这两个几乎相同答案的区别

wanna know the difference of these two almost same answers

我正在做一道 leetcode 题,你可以在这里查看:https://leetcode.com/problems/binary-tree-preorder-traversal 这是我第一次回答错误答案:

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

这是我第二次通过测试的答案:

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

如果你有一个 leetcode 帐户,你可以简单地点击上面的 link 并在代码区域复制我的两个答案和 运行 每个,然后你可以找到像“ [1,2,3]”,表示每个树节点只有左分支的树,只能通过第二个代码,而在第一个代码中,最左边节点的值(在本例中为 3)不包含在问题要求的向量。我想知道我的第一个答案有什么问题导致结果不同。

我知道第一个代码看起来很奇怪和乏味,我只是想知道为什么它不能正确工作。

非常感谢帮助我的各位。

前序遍历需要访问树中的所有节点。

在您的第一个版本中,您有这些行:

if(root->left) return preorderTraversal(root->left,res);
if(root->right) return preorderTraversal(root->right,res);

如果 root->left 不为空,将执行 return 语句,并导致函数执行在递归调用 preorderTraversal 后结束 return。

这意味着如果root->left不为空,则整个右子树将被访问。

出于一致性原因,第二个 if 也是错误的(没有理由 return 右子树,如果你不应该 return 左子树)。

您的第二个版本向左和向右执行递归(按此顺序),确保所有节点都按照预定标准访问。