Java 在我检查异常后引发异常的程序
我一定错过了一些非常简单的东西,因为这让我大吃一惊 我尝试使用CompleteBinaryTree(使用数组实现)实现堆。这个CompleteBinaryTree是一个Java 在我检查异常后引发异常的程序,java,arrays,exception,heap,binary-tree,Java,Arrays,Exception,Heap,Binary Tree,我一定错过了一些非常简单的东西,因为这让我大吃一惊 我尝试使用CompleteBinaryTree(使用数组实现)实现堆。这个CompleteBinaryTree是一个位置数组,其中每个位置包含一个元素。我正在为堆编写add(T)方法,其中T被插入到CompleteBinaryTree的下一个空闲位置,然后执行一个uptap过程,直到CompleteBinaryTree被排序。方法如下: private CompleteBinaryTree<T> tree = new Com
位置
数组,其中每个位置
包含一个元素。我正在为堆编写add(T)
方法,其中T
被插入到CompleteBinaryTree的下一个空闲位置,然后执行一个uptap过程,直到CompleteBinaryTree被排序。方法如下:
private CompleteBinaryTree<T> tree = new CompleteBinaryTree<T>();
private Position<T> entry = null;
public void add(T t) {
entry = tree.add(t);
if (entry.equals(tree.root())) {
return;
}
//continue to swap inserted element with its parent
//while it is smaller than its parent
while (entry.element().compareTo(tree.parent(entry).element()) < 0) {
Position<T> parent = tree.parent(entry);
Position<T> temp = entry;
entry = parent;
parent = temp;
}
}
下面是从CompleteBinaryTree
中使用的另外两种方法:
public Position<T> root() {
if (isEmpty()) throw new InvalidPositionException();
return array[1];
}
public Position<T> add(T t) {
if (last == array.length) {
// extend array
ArrayPosition[] temp = (ArrayPosition[]) new Object[array.length*2];
for (int i=1; i < array.length; i++) {
temp[i] = array[i];
}
array = temp;
}
array[last] = new ArrayPosition(last, t);
return array[last++];
}
当我第一次检查p是否为根时,如何因为p==root()而引发异常
但您并没有检查每个树.parent()
参数以查看它是否为根。只检查传递给该方法第一次调用的参数。每次执行循环时的主体都会将条目设置为新值,当循环循环循环时,您会将新的未选中值传递给树.parent()
。实际上,entry
的每个新值都比前一个值更接近根,因为整个点是在树上从子级向上移动到父级,即向根移动。有时,这个过程很可能会到达根,而且树中的元素越少,就越有可能到达根
解决此问题的一种方法是将根检查移动到while
条件:
while (!entry.equals(tree.root())
&& entry.element().compareTo(tree.parent(entry).element()) < 0) {
// ...
}
while(!entry.equals(tree.root())
&&entry.element().compareTo(tree.parent(entry.element())<0){
// ...
}
当然,在这种情况下,您不需要在循环之外执行当前的一次性检查
当我第一次检查p是否为根时,如何因为p==root()而引发异常
但您并没有检查每个树.parent()
参数以查看它是否为根。只检查传递给该方法第一次调用的参数。每次执行循环时的主体都会将条目设置为新值,当循环循环循环时,您会将新的未选中值传递给树.parent()
。实际上,entry
的每个新值都比前一个值更接近根,因为整个点是在树上从子级向上移动到父级,即向根移动。有时,这个过程很可能会到达根,而且树中的元素越少,就越有可能到达根
解决此问题的一种方法是将根检查移动到while
条件:
while (!entry.equals(tree.root())
&& entry.element().compareTo(tree.parent(entry).element()) < 0) {
// ...
}
while(!entry.equals(tree.root())
&&entry.element().compareTo(tree.parent(entry.element())<0){
// ...
}
当然,在这种情况下,您不需要在循环外执行当前的一次性检查。root()
可能正在引发异常。但是在引发异常之前,如果entry
是根,则该方法返回,但随后会引发异常,因为entry
是根。您调试了吗?在if(p==root())
或if(isEmpty())
上引发异常,最好移动抛出新的InvalidPositionException()
到新行root()
可能正在抛出。但是在抛出异常之前,如果entry
是根,则该方法将返回,但随后会抛出异常,因为entry
是根。您调试了吗?在if(p==root())
或if(isEmpty())
上引发异常,最好移动抛出新的InvalidPositionException()是的,我从来没有想过。这一切都是完全有道理的,而且现在看来一切都在正常运转。谢谢,但是,堆似乎没有被订购。当我将元素添加到堆中,然后打印堆的状态时,它的顺序与我将元素插入堆中的顺序相同。此外,无论我向堆中添加了什么元素——如果每次插入后打印根元素的值,它始终是我插入的第一个元素的值(这对我来说没有意义,因为在将新插入的元素交换到根位置时,它会抛出异常)。请参阅我的原始帖子,我将在其中添加“toString()”method@KOB,这个额外的问题不是这个问题的主题,但是我仍然注意到,尽管您的add()
方法从叶到根遍历树,但它似乎没有对任何节点进行任何重新排序。特别是,诸如entry=parent
之类的代码不会这样做——它只会更改本地变量entry
引用的节点。您可能还想交换位置
的内容,但这是我的推测。您解释得很好。我把它改成交换值,现在一切正常。谢谢啊,是的,我从没想过。这一切都是完全有道理的,而且现在看来一切都在正常运转。谢谢,但是,堆似乎没有被订购。当我将元素添加到堆中,然后打印堆的状态时,它的顺序与我将元素插入堆中的顺序相同。此外,无论我向堆中添加了什么元素——如果每次插入后打印根元素的值,它始终是我插入的第一个元素的值(这对我来说没有意义,因为在将新插入的元素交换到根位置时,它会抛出异常)。请参阅我的原始帖子,我将在其中添加“toString()”method@KOB,这个额外的问题不是这个问题的主题,但是我仍然注意到,尽管您的add()
方法从叶子到根遍历树,但它似乎没有做任何事情
while (!entry.equals(tree.root())
&& entry.element().compareTo(tree.parent(entry).element()) < 0) {
// ...
}