Do you have the entire tree structure on hand? Then you could do some sort of random traversal. For example, you could select a random item from a binary tree like so (pseudo-code):
sub randomNode(node):
randomVal = random(0, 3); // random value between 0 and 3
if(randomVal == 0):
return randomNode(node.left) if node.left != null else return node;
elseif(randomVal == 1):
return randomNode(node.right) if node.right != null else return node;
else
return node;
For an n-ary tree, you could have something like this:
sub randomNode(node):
randomVal = random(0, 2)
if(randomVal == 0):
return randomNode(node.children[random(0, node.children.length)]) if node.children.length != 0 else return node;
elseif(randomVal == 1):
return node;
Doing parent.children[random(parent.children.count)]
doesn't seem inefficient to me; it's what I've used in the algorithm above. As far as your last question, I guess it depends on how you've implemented your tree. If you've built up a tree structure on your own then you must have the whole tree structure on hand. If you're using a framework, then it depends on the implementation of that framework.