迭代二叉树时出现NullPointerException

时间:2013-10-19 17:17:22

标签: java nullpointerexception binary-tree

现在我不确定是否有人可以真正帮助我,因为这是一个相当大的代码需要通过,但任何帮助将不胜感激。这是我的相关代码:

public class BTree implements Iterable<String> {
    /** Left child */
    BTree left;
    /** Right Child */
    BTree right;
    /** Comparator to use for sorting */
    Comparator<String> comp;
    /** Parent node */
    BTree parent;
    /** String stored in this leaf */
    String s;
    /** # of iterators currently working on it */
    int active = 0;
    /** Size of the BTree */
    int size;

public void build(Iterable<String> iter, int numStrings) {
        if (this.active > 0) {
            throw new ConcurrentModificationException();
        } 
        else { 
            Iterator<String> itr = iter.iterator();
            while (numStrings != 0 && itr.hasNext()) {
                String s = itr.next();
                if (!this.contains(s)) {
                    this.insert(s);
                    this.size++;
                    numStrings--;
                }
            }
        }
    }

/**
 * Inserts the string into the given BTree
 * @param str - String to insert
 */
private void insert(String str) {
    if (this.s.equals("")) {
        this.s = str;
    }
    else if (this.comp.compare(str, this.s) > 0) {
        if (this.right == null) {
            BTree bt = BTree.binTree(this.comp);
            bt.s = str;
            this.right = bt;
            bt.parent = this;
        } 
        else {
            this.right.insert(str);
        }
    }
    else if (this.comp.compare(str, this.s) < 0) {
        if (this.left == null) {
            BTree bt = BTree.binTree(this.comp);
            bt.s = str;
            this.left = bt;
            bt.parent = this;
        }
        else {
            this.left.insert(str);
        }
    }
}



  private class BTreeIterator implements Iterator<String> {
            /** Current BTree being iterated over */
            BTree current;
            /** How many next() calls have there been */
            int count;
            /** Size of the BTree */
            int max;
            /** Constructor for BTreeIterator
             * @param current
             */
            BTreeIterator(BTree current) {
                this.current = current;
                this.count = 0;
                this.max = current.size;
                active++;
            }

            /** Returns true if there is another string to iterate over
             * @return boolean
             */
            public boolean hasNext() {
                if (this.count != this.max) {
                    return true;
                }
                else {
                    active--;
                    return false;
                }
            }

            /**
             * Returns the next string in the iterator
             * @return String
             */
            public String next() {
                if (this.count == 0) {
                    this.count++;
                    current = this.current.getLeftMost();
                    if (this.current.s.equals("")) {
                        throw new NoSuchElementException();
                    }
                    return this.current.s;
                }
                else if (this.current.right != null) {
                    this.current = this.current.right.getLeftMost();
                    this.count++;
                    return this.current.s;
                }
                else {
                    BTree tree = this.current;
                    while (tree.parent.right == tree) {
                        tree = tree.parent;
                    }
                    this.current = tree.parent;
                    this.count++;
                    return this.current.s;
                }
            }

            /** Throws an exception since we aren't removing anything from the trees
             */
            public void remove() {
                throw new UnsupportedOperationException();
            }

        }
    }

}

异常会在迭代器的next()方法的while (tree.parent.right == tree)行抛出。有趣的是,我的代码工作得很好用比较器按字典顺序和反向词典排序通过一个24000字的文件排序。它只在使用以下比较器时抛出异常:

class StringWithOutPrefixByLex implements Comparator<String> {

/**
 * compares o1 and o2
 * @param o1 first String in comparison
 * @param o2 second String in comparison
 * @return a negative integer, zero, or a positive integer 
 *         as the first argument is less than, equal to, or 
 *         greater than the second. 
 */
public int compare(String o1, String o2) {
    String s1, s2;
    if(o1.length() > 4){
        s1 = o1.substring(3);
    }
    else { 
        s1 = o1;
    }
    if(o2.length() > 4){
        s2 = o2.substring(3);
    }
    else { 
        s2 = o2;
    }
    return s1.compareTo(s2);
}
}

即使更奇怪,对于相同的文件,它可以很好地使用那个比较器,最多可达199个单词,但是一旦我有它就会累积200个单词,它就会破坏。

编辑:我已经确定异常是由于代码试图引用tree.parent.righttree.parentnull,但我无法弄清楚为什么它试图这样做。据我所知,我的代码永远不应该尝试调用null tree.parent,正如我在下面的评论所解释的那样。

1 个答案:

答案 0 :(得分:0)

好吧,你实际上没有显示足够的代码,但是,你的BTree的根节点怎么样?根节点中BTree.parent的值是多少? null

如果根节点具有空父节点,则在此while循环中,可能是:

                while (tree.parent.right == tree) {
                    tree = tree.parent;
                }

...将转到根节点,tree将设置为tree.parent,即null,然后while循环测试将失败,因为{{1}将尝试取消引用空指针。