程序在检查异常后抛出异常

时间:2016-04-01 17:32:37

标签: java arrays exception heap binary-tree

我必须错过非常简单的东西,因为这让我大吃一惊!

我正在尝试使用CompleteBinaryTree(使用数组实现)实现Heap。此CompleteBinaryTree是一个Position<T>数组,其中每个Position包含一个元素。我正在编写堆的add(T t)方法,其中t被插入到CompleteBinaryTree的下一个自由位置,然后执行一个upheap过程,直到订购了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;
        }
    }

将第一个元素添加到Heap中,但是当我尝试添加第二个元素时,InvalidPositionException行会引发while()。这是从CompleteBinaryTree类中抛出异常的地方:

    public Position<T> parent(Position<T> p) {
        if (p == root()) throw new InvalidPositionException();

        return array[((ArrayPosition) p).index/2];
    }

以下是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()而抛出异常?

修改

这是FullBinaryTree toString(),由堆toString()返回:

public String toString() {
    StringBuffer buf = new StringBuffer();

    for (int i = 1; i < last; i++) {
        buf.append(" ").append(array[i]);
    }

    return buf.toString();      
}

1 个答案:

答案 0 :(得分:2)

  

当我第一次检查p是否为root时,如何抛出异常,因为p == root()?

但是检查每个tree.parent()参数以查看它是否为root。您只检查传递给该方法的第一次调用的参数。每次执行while循环的主体时,它都会将entry设置为新值,当循环循环时,您将新的未选中循环值传递给tree.parent()。实际上,entry的每个新值都比前一个更接近根,因为整个点是将树从子向上移动到父,即向根移动。很可能有时这个程序会到达根目录,而且树中已经存在的元素越少,就越有可能。

解决此问题的一种方法是将根检查移至while条件:

while (!entry.equals(tree.root())
        && entry.element().compareTo(tree.parent(entry).element()) < 0) {
    // ...
}

在这种情况下,当然,您不需要在循环外执行的当前一次性检查。