I stumbled upon several implementations of algorithm to select a random node from a binary tree, and they all use subtree size property. However, I don't understand why knowing subtree size helps. Here's implementation A and B.
The general idea can be described in this pseudocode:
Node getRandomNode() {
Random seed = new Random;
int random = random.nextInt(this.size);
if (this.left.size == random)
return this;
if (this.left.size > random) {
return this.left.getRandomNode();
} else {
return this.right.getRandomNode();
}
}
I assume that the getRandomNode()
method is always called on the root of the tree.
As far as I see the randomality of choosing a node depends solely on the randomality of random
integer. In certain cases if random
repeats itself then getRandomNode()
will return the same node.
Also I don't understand how the algorithm can work in a complete binary tree. The size of each node subtree will always be an even number. So if random
is an even number the algorithm will not have a match on this line:
if (this.left.size == random)
return this;
and will only produce a random number if random
is an even number, which means that the algorithm is not random.
Am I missing something?
If I had to implement the algorithm I would just store an additional linked list where each node would have an index (like ArrayList
in Java) and then return the node from the list whose index equals a random number returned from random.nextInt()
.
Aucun commentaire:
Enregistrer un commentaire