I am trying to copy leafs (recursively) from a BST to a new BST that include the copied leafs only. Here is what I did:
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 }
The code seems to be right when it comes to compiling, visiting leafs and copying them. However, the root of the new tree ( dst
) always has one leaf only (the last leaf). Any ideas?
EX of the problem:
src
had these leafs: 4
15
19
23
dst
will only have 23
. Since the bug has already been found in the comments, here's a very superficially tested solution.
You can't blindly copy nodes; you need to create a BST structure.
You can do this by first copying the leaves to the left and the leaves to the right and then joining them in a suitable way.
Since you start with a BST, the greatest node in the left copy is smaller than the smallest node in the right copy.
This means that you will get a BST if you replace the leftmost left-pointer (which is null) in the right copy with the root of the left copy.
This may lead to a very unbalanced tree, of course.
If you want to balance it, you need a more sophisticated solution, which is left as an exercise.
Assuming this node structure:
struct node
{
int datum;
node* left;
node* right;
node(int v) : datum(v), left(nullptr), right(nullptr) {}
};
it would look something like this:
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;
}
}
I believe it's possible to make copy_leaves
also give you the leftmost node, which saves some top-down traversals, but it complicates the code so I'm leaving that as an exercise.
void copy_leaves(node * src, node *& dest)
{
if (!src) return;
dest = new node(src->data); // this should zero out the pointers, assuming you make one.
copy_leaves(src->left, dest->left);
copy_leaves(src->right, dest->right);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.