ArrayindexOutOfBoundsException,带有最佳二进制搜索树实现java

时间:2016-08-12 01:16:36

标签: java tree binary-search-tree indexoutofboundsexception

我正在努力在java中实现Optimal Binary Search Tree问题。对于我的程序,我正在读取一个txt文件,其中第一行是节点数,每个前一行由空格分隔,其中第一个元素是节点,第二个元素是概率。以下是我的程序读取的示例输入:

5
A 0.213
B 0.547
D 0.10
X 0.12
AAA 0.02

在我的程序中,我正在尝试创建一个打印方法,这样当我运行程序时,我可以看到它是什么节点,它的概率是什么,它的父亲是什么以及他们的孩子是什么。下面提供了一个节点的示例输出:

Node
Key: B
Probability: 21.3%
Parent: (null)
Left Child: A
Right Child: X

我现在遇到的问题是它正在读取树的根,但过了一段时间它会给我一个超出范围的索引。下面是我的打印树方法的代码

public static void printTree(String keys[], double prob[], int root[][]){
 System.out.println("");
int pos = root[1][keys.length-1];
int t=pos;

for(int i = 0; i < keys.length-1; i ++){

     System.out.println("Node Key "+ pos); 
     System.out.println("Key: "+ keys[pos]); 
     System.out.println("Probability: "+ prob[pos]);

     if(i ==0){
         System.out.println("Parent: null");
         System.out.println("Left Child: "+ keys[pos-1]);
         System.out.println("Right Child: "+ keys[pos+1]); 
         if(root[1][pos]==t){
             pos-=1;
         }
     }

     else{

         System.out.println("Parent: "+ keys[pos+1]);
         System.out.println("Left Child: "+ keys[pos-1]); //where the error is occurring
         System.out.println("Right Child: "+ keys[pos+1]);  
         pos--;
     }


     System.out.println("");
}
}

这是我运行代码时收到的输出:

Node
Key: B
B is the root

Node Key 2
Key: B
Probability: 0.547
Parent: null
Left Child: A
Right Child: D

Node Key 1
Key: A
Probability: 0.213
Parent: B
Left Child: null
Right Child: B

Node Key 0
Key: null
Probability: 0.0
Parent: A
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at OBST.printTree(OBST.java:62)
at OBST.main(OBST.java:155
  

显然我已经尝试增加和减小大小,但是当我这样做时,我仍然得到IndexOutofBoundsException。我相信问题是,它是在阅读根目录,然后它会在列表中下载并且不会停止。

如果有人可以帮我解决这个问题,我会非常感激!

编辑: 我重建了我的print方法以包含节点,但是我仍然得到一个ArrayIndexOutofBoundsException。以下是使用节点类

的更新方法
public static void printTree(int i, int j, int pos, String side, String keys[], double prob[], int root[][], Nodes[] node){

    int temp;       
    if(i<=j){

        temp = root[i][j];
        System.out.println("Node");
        System.out.println("Key: " + keys[pos]);

        System.out.println("Probability: "+ prob[pos]+" %");
        System.out.println("Parent: "+ keys[pos]);
        System.out.println(keys[temp] + " is the "+ side +" child of "+ keys[pos]);
        for(int k =0; k< keys.length-1; k++){

            if(keys[pos].equalsIgnoreCase(node[k].getKey())){
                if(side.equalsIgnoreCase("left")){
                    node[i].setLeftChild(keys[temp]);
                }
                else{
                    node[i].setRightChild(keys[temp]);
                }

            }

            System.out.println(" ");


        }
        constructTree(i,temp-1,temp,"left", keys, prob, root, node);  
        constructTree(temp+1,j,temp,"right", keys, prob,root, node);  

    }

这是我收到的输出:

Node
Key: B
Probability: 0.547 %
Parent: B
A is the left child of B





Node
Key: B
Probability: 0.547 %
Parent: B
X is the right child of B





Node
Key: X
Probability: 0.12 %
Parent: X
D is the left child of X





Node
Key: X
Probability: 0.12 %
Parent: X
AAA is the right child of X



Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
at OptimalBT.Optimal.constructTree(Optimal.java:117)
at OptimalBT.Optimal.constructTree(Optimal.java:127)
at OptimalBT.Optimal.main(Optimal.java:90)

2 个答案:

答案 0 :(得分:1)

我假设您尝试将二叉树表示为二维数组。

在你的代码中写道:

 System.out.println("Parent: "+ keys[pos+1]);
 System.out.println("Left Child: "+ keys[pos-1]); 
 System.out.println("Right Child: "+ keys[pos+1]); 

这里有几个问题。

首先,您的代码暗示正确的孩子与父母位于同一位置(两者都在[pos + 1]处)。这是不正确的。正确的子节点与父节点不是同一节点。

其次,你的代码暗示左边的孩子在按键[pos-1],而右边的孩子在按键[pos + 1]。这是不正确的。对于阵列中位置“K”的任何节点,该节点的左子节点位于“2K”位置,该节点的右子节点位于“2K + 1”位置。

这是我在阿尔伯塔大学CS网站上获得的一幅精彩图片。它应该有助于您了解如何使用2d数组索引来表示二叉树。

enter image description here

Source

我希望你的输入实际上是这种格式,而你却没有意识到。这意味着你实际上有以下输入:

节点{name,parent,left_child,right_child,chance}

Node1 {A, null, B, D, 21.3}
Node2 {B, A, X, AAA, 54.7}
Node3 {D, A, null, null, 10.0}
Node4 {X, B, null, null, 12.0}
Node5 {AAA, B, null, null, 2.0} 

答案 1 :(得分:0)

指数不要像这样包裹。您的数组键的索引从0到keys.length-1。因此当你在pos为0时执行System.out.println("Left Child: "+ keys[pos-1]);时,你试图访问索引-1,正如你在错误消息中看到的那样,你的程序无法访问索引-1。

然而,我在努力找出你想要的东西时遇到了一些困难。我也不知道你如何插入节点,所以我不能说打印是否正确。所以我的答案有限。

但根据您的评论,您希望它在keys.length-1发生时访问索引4。要做到这一点,你需要环绕。最简单的方法是使用modulo。因此,您不必使用keys[pos-1],而是使用keys[(pos-1)%keys.length]keys[(pos+1)%keys.length]