我正在研究二叉搜索树的分配,当我看到我在树上添加一个数字然后尝试检查它的前任/后继(将其放入)时,我正在测试我认为是成品的产品依次遍历然后检查索引之前/之后的索引),这只是...行不通。每当我尝试检查刚放在树中间的值的前任/后任时,它都会出现ArrayIndexOutOfBoundsException异常。重要说明是,仅使用inordertraverse(在代码中称为printInOrder)进行打印即可完美地工作。
由于打印了有序遍历,所以我可以认为我的树不是问题。唯一的另一件事是数组,对不对?我缺少明显的东西吗?
这是代码!
public class BST implements BSTInterface
{
//Variables/Fields
private BNode root;
//Constructors
public BST(int data)
{
root = new BNode(data);
}
//Public Methods
public boolean add(int data)
{
if(!contains(data))
{
root = addEntry(root, data);
return true;
}
else
return false;
}
public boolean contains(int data)
{
return containsNode(root, data);
}
public boolean remove(int data)
{
if(contains(data))
{
root = deleteNode(root, data);
return true;
}
else
return false;
}
public int[] toArray()
{
int[] output = new int[root.numNodes()];
inorderTraverse(output, 0, root);
return output;
}
public void printInOrder()
{
printIn(root);
}
public void printPreOrder()
{
printPre(root);
}
public void printPostOrder()
{
printPost(root);
}
//Private methods/classes
private class BNode
{
private int data;
private BNode leftChild;
private BNode rightChild;
public BNode(int data)
{
this.data = data;
leftChild = null;
rightChild = null;
}
public int getData()
{
return data;
}
public void setData(int newData)
{
data = newData;
}
public BNode getLeftChild()
{
return leftChild;
}
public BNode getRightChild()
{
return rightChild;
}
public void setRightChild(BNode node)
{
rightChild = node;
}
public void setLeftChild(BNode node)
{
leftChild = node;
}
public int numNodes()
{
int leftNum = 0;
int rightNum = 0;
if(leftChild != null)
leftNum = leftChild.numNodes();
if(rightChild != null)
rightNum = rightChild.numNodes();
return 1+leftNum+rightNum;
}
}
private BNode addEntry(BNode current, int data)
{
if(current == null)
return new BNode(data);
if(data < current.getData())
current.setLeftChild(addEntry(current.getLeftChild(), data));
else if(data > current.getData())
current.setRightChild(addEntry(current.getRightChild(), data));
return current;
}
private boolean containsNode(BNode current, int entry)
{
if(current == null)
return false;
if(entry == current.getData())
return true;
if(entry < current.getData())
return containsNode(current.getLeftChild(), entry);
else
return containsNode(current.getRightChild(), entry);
}
private BNode deleteNode(BNode current, int data)
{
if(current == null)
return null;
if(data == current.getData())
{
if(current.getLeftChild() == null && current.getRightChild() == null) //No children
return null;
if(current.getRightChild() == null) //Only right child
return current.getLeftChild();
if(current.getLeftChild() == null) //Only left child
return current.getRightChild();
int smallestChild = findSmallest(current.getRightChild());
current.setData(smallestChild);
current.setRightChild(deleteNode(current.getRightChild(), smallestChild));
return current;
}
if(data < current.getData())
{
current.setLeftChild(deleteNode(current.getLeftChild(), data));
return current;
}
else
current.setRightChild(deleteNode(current.getRightChild(), data));
return current;
}
private int findSmallest(BNode root)
{
return root.getLeftChild() == null ? root.getData() : findSmallest(root.getLeftChild());
}
private void inorderTraverse(int[] array, int count, BNode node)
{
if(node != null)
{
inorderTraverse(array, count, node.getLeftChild());
array[count] = node.getData();
count++;
inorderTraverse(array, count, node.getRightChild());
}
}
private void printIn(BNode node)
{
if(node != null)
{
printIn(node.getLeftChild());
System.out.print(node.getData() + " ");
printIn(node.getRightChild());
}
}
private void printPre(BNode node)
{
if(node != null)
{
System.out.print(node.getData() + " ");
printPre(node.getLeftChild());
printPre(node.getRightChild());
}
}
private void printPost(BNode node)
{
if(node != null)
{
printPost(node.getLeftChild());
printPost(node.getRightChild());
System.out.print(node.getData() + " ");
}
}
}
以及驱动程序:
import java.util.Scanner;
public class BSTDemoReel
{
public static void main(String[] args)
{
System.out.println("This search tree only handles integers! Thanks in advance!\n\n");
Scanner keyboard = new Scanner(System.in);
//Variables
String input;
String choice = "";
int num;
int index;
boolean found;
//Starting
System.out.println("Please enter the initial sequence of values:\n");
input = keyboard.nextLine();
String[] splitInput = input.split(" ");
int[] intInputArray = new int[splitInput.length];
for(int count = 0; count < splitInput.length; count++)
{
intInputArray[count] = Integer.parseInt(splitInput[count]);
}
BST searchTree = new BST(intInputArray[0]);
for(int count = 1; count < intInputArray.length; count++)
{
searchTree.add(intInputArray[count]);
}
System.out.print("Pre-order: ");
searchTree.printPreOrder();
System.out.println();
System.out.print("In-order: ");
searchTree.printInOrder();
System.out.println();
System.out.print("Post-order: ");
searchTree.printPostOrder();
System.out.println();
//Menu
while(!choice.equals("E"))
{
System.out.print("Command? ");
choice = keyboard.next();
choice = choice.toUpperCase();
switch(choice)
{
case "I": num = keyboard.nextInt();
if(searchTree.contains(num))
System.out.println(num + " already exists. Please try again.");
else
{
searchTree.add(num);
System.out.print("In-order: ");
searchTree.printInOrder();
System.out.println();
}
break;
case "D": num = keyboard.nextInt();
if(!searchTree.contains(num))
System.out.println(num + " does not exist. Please try again.");
else
{
searchTree.remove(num);
System.out.print("In-order: ");
searchTree.printInOrder();
System.out.println();
}
break;
case "P": num = keyboard.nextInt();
if(searchTree.contains(num))
{
int[] array = searchTree.toArray();
index = 0;
found = false;
while(!found)
{
if(num == array[index])
found = true;
else
index++;
}
if(index != 0)
System.out.println(array[index-1]);
else
System.out.println("That was the first one!");
}
else
System.out.println(num + " does not exist! Please try again!");
break;
case "S": num = keyboard.nextInt();
if(searchTree.contains(num))
{
int[] array = searchTree.toArray();
index = 0;
found = false;
while(!found)
{
if(num == array[index])
found = true;
else
index++;
}
if(index != array.length-1)
System.out.println(array[index+1]);
else
System.out.println("That was the last one!");
}
else
System.out.println(num + " does not exist! Please try again!");
break;
case "E": System.out.println("Was a tricky one! Thanks for playing ;P");
break;
case "H": System.out.println("I Insert a value\n" +
"D Delete a value\n" +
"P Find predecessor\n" +
"S Find successor\n" +
"E Exit the program\n" +
"H Display this message");
break;
default: System.out.println("Invalid command. Type H for help.");
break;
}
}
keyboard.close();
}
}
答案 0 :(得分:0)
如果您添加两行代码以打印出employee
返回的数组,然后再进入searchTree.toArray()
循环,该循环将检查数组以查找由while
指定的值或P
命令,您将看到问题的原因。数组未正确填写。期望的值可能不会出现在数组中,这意味着S
永远不会变为True,并且found
循环将继续递增while
直到其超过数组的大小并触发您看到的异常。
由于该数组应该由index
填充,因此这表明该函数未正确执行其工作。行为异常的原因是它对自身的内部递归调用不会为调用者修改inorderTraverse()
变量的值。 count
是一个简单的count
变量,因此递归调用中的int
语句不会影响调用函数中count++
的值。
您最好的选择是更改count
以使其返回下一个应填写的数组元素的索引,或者将inorderTraverse()
更改为包含{{1}的Object }成员,其值在递归调用的函数中递增后将对调用方可见。
由于这是一项作业,因此我不会显示该程序的正确版本。更改很小,因此鉴于您到目前为止所做的一切,我希望您在使其生效方面不会遇到很多麻烦。
顺便说一句,您的程序缺少count
,int
和printIn()
的实现。它们并不难编写,但是对于任何可能有兴趣帮助您解决问题的人来说,这都是一个额外的障碍。这可能至少是没有其他人提供答案的原因的至少一部分。您使人们越容易重现问题,获得答案的可能性就越大。