C++ 在C+中(递归地)复制二叉搜索树中的叶子+;

C++ 在C+中(递归地)复制二叉搜索树中的叶子+;,c++,recursion,binary-search-tree,C++,Recursion,Binary Search Tree,我正在尝试将leaf(递归地)从一个BST复制到一个只包含复制的leaf的新BST。以下是我所做的: 27 void tree::copy_leafs(node * src, node *& dst) { 28 if (!src) //Case 1: current node is NULL 29 return; 30 if (!src->left && !src->

我正在尝试将leaf(递归地)从一个BST复制到一个只包含复制的leaf的新BST。以下是我所做的:

27 void tree::copy_leafs(node * src, node *& dst) {
28     if (!src)                                 //Case 1: current node is NULL
29         return;
30     if (!src->left && !src->right) {          //Case 2: current node is a leaf
31         dst = new node;
32         dst->data = src->data;
33         dst->left = NULL;
34         dst->right = NULL;
35         copy_leafs(src->left, dst->left);
36         copy_leafs(src->right, dst->right);
37     } else {                                  //Case 3: current node is NOT a leaf
38         copy_leafs(src->left, dst);
39         copy_leafs(src->right, dst);
40    }
41 }
在编译、访问和复制leaf时,代码似乎是正确的。但是,新树的根(
dst
)始终只有一个叶(最后一个叶)。有什么想法吗

问题的排除:

  • 假设
    src
    有这些叶子:
    4
    15
    19
    23
  • 完成此功能后,
    dst
    将只有
    23

由于在评论中已经发现了该漏洞,下面是一个经过表面测试的解决方案

不能盲目复制节点;您需要创建一个BST结构。
您可以先将叶复制到左侧,然后将叶复制到右侧,然后以适当的方式将它们连接起来

因为从BST开始,所以左侧副本中最大的节点比右侧副本中最小的节点小。
这意味着,如果将右副本中最左边的指针(为null)替换为左副本的根,则将获得BST

当然,这可能会导致非常不平衡的树。
如果你想平衡它,你需要一个更复杂的解决方案,这只是一个练习

假设此节点结构:

struct node
{
    int datum;
    node* left;
    node* right;
    node(int v) : datum(v), left(nullptr), right(nullptr) {}
};
它看起来像这样:

node* copy_leaves(const node* tree)
{
    if (!tree)
    {
        return nullptr;
    }
    if (!tree->left && !tree->right)
    {
        return new node(tree->datum);
    }

    // Not a leaf; recurse
    node* left_leaves = copy_leaves(tree->left);
    node* right_leaves = copy_leaves(tree->right);
    if (!left_leaves)
    {
        return right_leaves;
    }
    else if (!right_leaves)
    {
        return left_leaves;
    }
    else
    {
        // Locate the leftmost node in the right tree.
        node* smallest_right = right_leaves;
        while (smallest_right->left != nullptr)
        {
            smallest_right = smallest_right->left;
        }
        // And attach the left leaf tree.
        smallest_right->left = left_leaves;
        return right_leaves;
    }
}

我相信可以让
copy\u leaves
也给你最左边的节点,这节省了一些自上而下的遍历,但它使代码复杂化,所以我把它作为一个练习。

第35/36行是否定的。对
copy\u leafs
的所有调用都传递相同的
dst
dst
唯一赋值的地方是第31行。因此,该函数总是要创建一个纯叶树(可能通过多次覆盖
dst
)!!没错,这只是一片叶子(死胡同)@梅尔波梅内多你知道怎么解决吗@melpomeneBut树应该是什么样子?这只是复制整个树,而不仅仅是树叶。虽然这个代码片段可以解决这个问题,但确实有助于提高您的文章质量。请记住,您将在将来回答读者的问题,这些人可能不知道您的代码建议的原因。还请尽量不要用解释性注释挤满你的代码,这会降低代码和解释的可读性!
node* copy_leaves(const node* tree)
{
    if (!tree)
    {
        return nullptr;
    }
    if (!tree->left && !tree->right)
    {
        return new node(tree->datum);
    }

    // Not a leaf; recurse
    node* left_leaves = copy_leaves(tree->left);
    node* right_leaves = copy_leaves(tree->right);
    if (!left_leaves)
    {
        return right_leaves;
    }
    else if (!right_leaves)
    {
        return left_leaves;
    }
    else
    {
        // Locate the leftmost node in the right tree.
        node* smallest_right = right_leaves;
        while (smallest_right->left != nullptr)
        {
            smallest_right = smallest_right->left;
        }
        // And attach the left leaf tree.
        smallest_right->left = left_leaves;
        return right_leaves;
    }
}