简体   繁体   English

头指针不包含二叉树中的子节点

[英]Head pointer doesn't contain child nodes in Binary Tree

I'm copying a binary tree and I'm having an issue where my root pointer of the new tree ends up only containing the 1st node that is to be copied, and no others.我正在复制一棵二叉树,但我遇到了一个问题,即新树的根指针最终只包含要复制的第一个节点,而没有其他节点。 I believe the issue has something to do with the fact that when I pass in the pointers in the recursion in the helper function, for some reason they are not being reassigned to the new nodes memory address.我相信这个问题与这样一个事实有关,即当我在辅助函数的递归中传递指针时,由于某种原因,它们没有被重新分配给新节点的内存地址。 Like in helper(t1->left, t2->left) t2->left never actually ends up becoming the value I intend it to have, it stays null.就像在helper(t1->left, t2->left) t2->left 中一样,实际上并没有最终成为我想要的值,它保持为空。

   bool first_time = true;
   TreeNode* ref = NULL;
    void helper(TreeNode* t1, TreeNode* t2) {
        if(t1) {
            t2 = new TreeNode(t1->val);
            if(first_time) {
                ref = t2;
                first_time = false;
            }
            helper(t1->left, t2->left);
            helper(t1->right, t2->right);
        }
        
    }
    TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
        TreeNode* tree1 = new TreeNode(1);
        tree1->left = new TreeNode(2);
        tree1->right = new TreeNode(3);
        helper(tree1, NULL);
        return ref;
    }

check your globals first_time and ref .检查您的全局变量first_timeref

if (first_time) {
  ref = t2;           // global
  first_time = false; // global set to never go here again
}

It is actually the root of your problem - you change other global variable ref once you pass first node to your function and never change it anywhere afterwards.它实际上是您问题的根源 - 一旦您将第一个节点传递给您的函数,您就更改了其他全局变量ref并且此后永远不会在任何地方更改它。 So, basically, on every recursive call you leak memory with dangling pointers.因此,基本上,在每次递归调用中,您都会使用悬空指针泄漏内存。 Probably, you should pass parameter first_time to your function and probably pass ref as parameter as assignable可能,您应该将参数first_time传递给您的函数,并且可能将ref作为参数传递为可分配的

You have a couple of problems here.你在这里有几个问题。

First, ref and first_time are serious flaws and you should avoid writing code with such global state.首先, reffirst_time是严重的缺陷,您应该避免编写具有这种全局状态的代码。 It is not reentrant, and not thread-safe.它不是可重入的,也不是线程安全的。

Second, you're trying to write to the t2 pointer and change the caller's pointer to that value.其次,您尝试写入 t2 指针并将调用者的指针更改为该值。 However, you're passing in a copy of t2 so writes to it will be lost.但是,您传入的是 t2 的副本,因此写入的内容将丢失。

It doesn't take much to clean it up, just change your function to take a reference to pointer and writes to t2 will persist back to callers.清理它不需要太多,只需更改您的函数以获取对指针引用,并且对 t2 的写入将持续返回给调用者。 Note, t2 is an "out" parameter, and so the initial caller will get the tree copy returned through this pointer.请注意,t2 是一个“out”参数,因此初始调用者将通过此指针获取返回的树副本。

Here's a fixed version:这是一个固定版本:

void helper(TreeNode* t1, TreeNode*& t2) {
    if(t1) {
        t2 = new TreeNode(t1->val);
        helper(t1->left, t2->left);
        helper(t1->right, t2->right);
    }  
}

Here's what your test function would look like:这是您的测试函数的样子:

TreeNode* copyTest() {
    TreeNode* tree1 = new TreeNode(1);
    tree1->left = new TreeNode(2);
    tree1->right = new TreeNode(3);
    
    TreeNode* tree2 = nullptr;
    helper(tree1, tree2);  // tree2 is written to as new root.
    return tree2;
}

But out parameters are generally discouraged if they are not needed.但是如果不需要 out 参数,通常不鼓励使用。

Why not write your copyTree function to return a pointer to the copied tree?为什么不编写 copyTree 函数来返回指向复制树的指针? Basically get rid of the 2nd argument in, and allocate a copy of the current tree, recursing down, attaching each child copy to the current node parent copy, and return the parent:基本上去掉in的第二个参数,并分配当前树的副本,向下递归,将每个子副本附加到当前节点的父副本,并返回父节点:

TreeNode* copyTree(TreeNode* tree) {
    TreeNode* ret = nullptr;
    if (tree) {
        ret = new TreeNode(tree->val);
        ret->left = copyTree(tree->left);
        ret->right = copyTree(tree->right);
    }
    return ret;
}

This isn't a great approach to protecting against leaks unless you're really careful, but it's good for understanding the recursion and tree structure.除非您非常小心,否则这不是防止泄漏的好方法,但它有助于理解递归和树结构。

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

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