Java 在我检查异常后引发异常的程序

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

我一定错过了一些非常简单的东西,因为这让我大吃一惊

我尝试使用CompleteBinaryTree(使用数组实现)实现堆。这个CompleteBinaryTree是一个
位置
数组,其中每个
位置
包含一个元素。我正在为堆编写
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()add()
方法从叶到根遍历树,但它似乎没有对任何节点进行任何重新排序。特别是,诸如
entry=parent
之类的代码不会这样做——它只会更改本地变量
entry
引用的节点。您可能还想交换
位置
的内容,但这是我的推测。您解释得很好。我把它改成交换值,现在一切正常。谢谢啊,是的,我从没想过。这一切都是完全有道理的,而且现在看来一切都在正常运转。谢谢,但是,堆似乎没有被订购。当我将元素添加到堆中,然后打印堆的状态时,它的顺序与我将元素插入堆中的顺序相同。此外,无论我向堆中添加了什么元素——如果每次插入后打印根元素的值,它始终是我插入的第一个元素的值(这对我来说没有意义,因为在将新插入的元素交换到根位置时,它会抛出异常)。请参阅我的原始帖子,我将在其中添加“toString()”method@KOB,这个额外的问题不是这个问题的主题,但是我仍然注意到,尽管您的
add()
方法从叶子到根遍历树,但它似乎没有做任何事情
while (!entry.equals(tree.root())
        && entry.element().compareTo(tree.parent(entry).element()) < 0) {
    // ...
}