我试图返回BST的第n项所持有的数据,我试图用计数器进行顺序遍历,当计数器大于n时,返回当前节点。我当前的代码似乎总是返回第一项,我无法看到我的逻辑错误。我只写了第n和inOrder方法,其余的都提供了。我想我经常递增我的柜台,是因为我或其他事情做错了。我将发布主要方法,我也会在下面进行测试。
import java.util.NoSuchElementException;
public class BST {
private BTNode<Integer> root;
public BST() {
root = null;
}
public boolean insert(Integer i) {
BTNode<Integer> parent = root, child = root;
boolean goneLeft = false;
while (child != null && i.compareTo(child.data) != 0) {
parent = child;
if (i.compareTo(child.data) < 0) {
child = child.left;
goneLeft = true;
} else {
child = child.right;
goneLeft = false;
}
}
if (child != null)
return false; // number already present
else {
BTNode<Integer> leaf = new BTNode<Integer>(i);
if (parent == null) // tree was empty
root = leaf;
else if (goneLeft)
parent.left = leaf;
else
parent.right = leaf;
return true;
}
}
public int greater(int n) {
if (root == null) {
return 0;
}
else {
return n;
}
}
int c = 0;
public int nth(int n) throws NoSuchElementException {
BTNode<Integer> node = null;
if (root == null) {
throw new NoSuchElementException("Element " + n + " not found in tree");
}
else {
if (root != null){
node = inOrder(root, n);
}
}
return node.data;
}
public BTNode inOrder(BTNode<Integer> node, int n) {
c++;
while (c <= n) {
if (node.left != null) {
inOrder(node.left, n);
}
c++;
if (node.right != null) {
inOrder(node.right, n);
}
}
return node;
}
}
class BTNode<T> {
T data;
BTNode<T> left, right;
BTNode(T o) {
data = o;
left = right = null;
}
}
public class bstTest {
public static void main(String[] args) {
BST tree = new BST();
tree.insert(2);
tree.insert(5);
tree.insert(7);
tree.insert(4);
System.out.println(tree.nth(2));
}
}
答案 0 :(得分:1)
你应该考虑的一个不变量是当n = sizeOfLeftSubtree + 1时,然后返回该节点。如果n较小,则向左走。如果n更大,则右移并通过sizeOfLeftSubtree + 1减少n。请注意,我将n = 1映射到第一个元素(最左边的元素)。
你可以简单地递归地计算子树的大小,或者你可以在每个根存储大小(每个节点是子树的根)修改你的插入方法(保存在堆栈/队列中所有被访问的节点,如果是添加新节点只需将所有大小增加1)。
如果存储大小,复杂度将为O(log n)。如果不是,那么可能变成O(n ^ 2)。
public int nth(int n) throws NoSuchElementException {
if( sizeOfTree(this.root) < n || n < 1)
throw new NoSuchElementException("Element " + n + " not found in tree");
BTNode<Integer> root = this.root;
boolean found = false;
do{
int sizeOfLeftSubtree = sizeOfTree(root.left);
if( sizeOfLeftSubtree + 1 == n ){
found = true;
}else if( n < sizeOfLeftSubtree+1 ){
root = root.left;
}else if( sizeOfLeftSubtree+1 < n ){
root = root.right;
n -= sizeOfLeftSubtree+1;
}
}while( !found );
return root.data;
}
public int sizeOfTree(BTNode<Integer> root){
if( root == null )
return 0;
else
return sizeOfTree(root.left) + 1 + sizeOfTree(root.right);
}
答案 1 :(得分:0)
您不能在node
方法中更改inOrder
。
public BTNode inOrder(BTNode<Integer> node, int n) {
c++;
while (c <= n) {
if (node.left != null) {
// **** Add this - or something.
node = inOrder(node.left, n);
}
c++;
if (node.right != null) {
// **** Add this - or something.
node = inOrder(node.right, n);
}
}
return node;
}
不建议这是您尝试修复的错误,但这肯定是代码的问题。