我正在努力在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)
答案 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数组索引来表示二叉树。
我希望你的输入实际上是这种格式,而你却没有意识到。这意味着你实际上有以下输入:
节点{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]
。