我的方法是假设从BST返回一个随机节点,但它无法正常工作,我不确定为什么。假设该方法在递增计数器时使用前序遍历来遍历树。一旦计数器等于随机生成的数字,就会返回节点。
// get random node
public Node getRandomNode(Node root) {
// get random value between 0 to size of BST
Random ran = new Random();
int ranNum = ran.nextInt(size + 1);
Node temp = root;
System.out.println("random number is: " + ranNum);
root = getRandomNode(ranNum, temp);
return root;
}
int count = 0;
public Node getRandomNode(int ranNum, Node temp) {
// traverse through the tree and increment count until count is the
// random number,
// in which case return the node it is on
if (temp != null && count != ranNum) {
count++;
temp = getRandomNode(ranNum, temp.left);
System.out.println(temp.data);
temp = getRandomNode(ranNum, temp.right);
}
// if count is equal to the randomly generated number
return temp;
}
编辑: 使用BFS
public Node getRandomNode(int ranNum, int count, Node temp) {
if(temp == null)
return null;
Queue<Node> q = new LinkedList<Node>();
q.add(temp);
count++;
while(!q.isEmpty() && count != ranNum) {
Node n = q.remove();
System.out.println(" " + n.data);
if(count == ranNum) {
System.out.println("final node: " + n.data);
return n;
}
if(n.left != null) {
q.add(n.left);
count++;
}
if(n.right != null) {
q.add(n.right);
count++;
}
}
return temp;
}
答案 0 :(得分:2)
您的问题出在递归调用中。假设随机数为1,您可能希望返回的结果是从左子树到达的第一个节点。你的代码会说temp = getRandomNode(ranNum, temp.left);
,此时临时变量会保存正确的答案,然后你说temp = getRandomNode(ranNum, temp.right);
,此时你的临时变量会有错误的答案。
编辑: 我决定尝试快速修复您的BFS实施(快速=未经测试)。请注意,我正在努力让我的代码尽可能地靠近你的代码,所以我避免对你的算法进行任何更改。
public Node getRandomNode(Node temp, int ranNum) {
if(temp == null)
return null;
Queue<Node> q = new LinkedList<Node>();
q.add(temp);
int count = 0;
while(!q.isEmpty() && count <= ranNum) {
Node current = q.remove();
System.out.println(" " + result.data);
if(count == ranNum) {
System.out.println("final node: " + n.data);
return n;
}
if(n.left != null) {
q.add(n.left);
}
if(n.right != null) {
q.add(n.right);
}
count++
}
return null;
}
EDIT2: 决定修复你的其他版本(仍然试图非常接近你原来的设计)。
// get random node
public Node getRandomNode(Node root) {
// get random value between 0 to size of BST
Random ran = new Random();
int ranNum = ran.nextInt(size + 1);
System.out.println("random number is: " + ranNum);
return getRandomNode(ranNum, root);
}
int count = 0;
public Node getRandomNode(int ranNum, Node node) {
// traverse through the tree and increment count until count is the
// random number,
// in which case return the node it is on
if (node == null || count == ranNum) {
return node;
}
count++;
temp = getRandomNode(ranNum, temp.left);
if (temp != null) {
return temp;
}
return getRandomNode(ranNum, temp.right);
}
答案 1 :(得分:0)
您的实现并非完全随机,因为您正在根据计数(随机选取)检索随机节点,但不是随机遍历的! 当且仅当树为空时,树应该返回null。 因为你已经根据树的大小生成了随机数。
树有两条路径是向右还是向左......任何一条路都应该是随机的! 并且应该通过方法调用通过其中一个(除非分支已经用尽)。 我将count变量从field更改为方法参数&#39;因为它似乎是临时的,与class无关 因此,您不必重复每次使用课程的计数,这是一个很好的做法。 *另一个问题是你检查null如果一方有一个更少的话 数字比另一个使函数退出,因为节点是 如果这发生在左侧遍历它,则右边将替换临时值,但如果它发生在另一方面它可能返回null! 顺便认为这是伪代码我从来没有测试过它:)
public Node getRandomNode(Node root) {
Random ran = new Random();
int ranNum = ran.nextInt(size + 1);
Node temp = root;
System.out.println("random number is: " + ranNum);
root = getRandomNode(ranNum, temp,0);
return root;
}
public Node getRandomNode(int ranNum, Node temp, int count ) {
// traverse through the tree and increment count until count is the
// random number,
// in which case return the node it is on
if (temp != null && count != ranNum) {
count++;
Random pathRan = new Random();
int pathNo= pathRan.nextInt(2);
Node temp2 = null;
if(pathNo == 0){//if 0 go to left
temp2 = getRandomNode(ranNum, temp.left,count);
if(temp2 == null){//this means that this path has nodes less than count ,so try the right.
temp2 = getRandomNode(ranNum, temp.right,count);
}
}else{//go to right
temp2 = getRandomNode(ranNum, temp.right,count);
if(temp2 == null){//this means that this path has nodes less than count ,so try the left.
temp2 = getRandomNode(ranNum, temp.left,count);
}
}
return temp2;
}
// if count is equal to the randomly generated number
return temp;
}