Java 获取BST的第n项

Java 获取BST的第n项,java,binary-search-tree,Java,Binary Search Tree,我试图返回BST的第n项所持有的数据,我试图使用计数器进行顺序遍历,当计数器大于n时,返回当前节点。我当前的代码似乎总是返回第一项,我看不出我的逻辑哪里错了。我只编写了第n个和第I个方法,其余的都提供了。我想我经常增加我的计数器,这是原因还是我做错了什么。我将在下面发布我正在测试的主要方法 import java.util.NoSuchElementException; public class BST { private BTNode<Integer> root;

我试图返回BST的第n项所持有的数据,我试图使用计数器进行顺序遍历,当计数器大于n时,返回当前节点。我当前的代码似乎总是返回第一项,我看不出我的逻辑哪里错了。我只编写了第n个和第I个方法,其余的都提供了。我想我经常增加我的计数器,这是原因还是我做错了什么。我将在下面发布我正在测试的主要方法

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));
    }
}
import java.util.NoSuchElementException;
公共类BST{
私有节点根;
公共BST(){
root=null;
}
公共布尔插入(整数i){
BTNode父节点=根节点,子节点=根节点;
布尔goneLeft=false;
while(child!=null&&i.compareTo(child.data)!=0){
父母=子女;
if(i.compareTo(子数据)<0){
child=child.left;
goneLeft=真;
}否则{
child=child.right;
goneLeft=假;
}
}
if(child!=null)
return false;//编号已存在
否则{
BTNode叶=新的BTNode(i);
if(parent==null)//树为空
根=叶;
else if(goneLeft)
parent.left=叶;
其他的
parent.right=叶;
返回true;
}
}
公共整数大于整数(整数n){
if(root==null){
返回0;
}
否则{
返回n;
}
}
int c=0;
公共int-n(int-n)抛出NoTouchElementException{
BTNode=null;
if(root==null){
抛出新的NoSuchElementException(“在树中找不到元素”+n+);
}
否则{
if(root!=null){
节点=顺序(根,n);
}
}
返回node.data;
}
公共BTNode索引(BTNode节点,int n){
C++;

而(c在
inoder
方法中,不更改
节点

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;
}
公共BTNode索引(BTNode节点,int n){
C++;

虽然(c一个不变量,你应该考虑的是,当n=sieZoFrEfft子树+ 1时,然后返回那个节点。如果n小于,则向左移动。如果n大于,则向右,用sisifof左子树+ 1来减少n。注意,我将n=1映射到第一个元素(最左边的元素)。

可以简单地递归计算子树的大小,也可以在每个根(每个节点都是子树的根)存储大小,修改插入方法(将访问的所有节点保存在堆栈/队列中,如果添加了新节点,则只需将所有大小增加1)

如果存储了大小,则复杂性将为O(logn)。如果不存储,则可能会变为O(n^2)

public int-n(int-n)抛出NoTouchElementException{
if(sizeOfTree(this.root)
每次调用方法时都要修改字段,所以是的。增加太多我不想增加,直到我位于最左边的项右侧?然后每次调用该方法时我都要增加?这样,如果node.left为null,我就可以增加,然后增加c。这样做正确吗?效果更好,但如果我将n传递为1,它会返回它是根,而不是最左边的项。我需要在其他地方增加c…谢谢,这比我尝试的要有效得多。
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);
}