红黑树remove()函数抛出NullPointer

时间:2015-12-10 06:01:24

标签: java data-structures tree binary-search-tree red-black-tree

我正在尝试用Java实现一个红黑树,而我的remove()函数遇到的问题是它抛出NullPointerException

首先,我创建一个根并插入我的红黑树,如下所示:

public void create(String word) { root = new RedBlackTree<String>(word); }
public void insert(String word) { root.add(word); }

然后我有一个GUI,我可以选择使用word删除某个节点。出于某种原因,我必须手动在r-b树中插入我想要删除的相同单词。 (顺便说一下,插入函数会增加一个单词出现变量,只需将节点的数据值加一两。所以每个节点都有一个唯一的单词。)插入后,我可以在没有NullPointerException的情况下删除它。但是,如果我在手动插入之前尝试删除该单词,则会抛出异常。即使单词基于我的insert()函数在树中,树也似乎找不到它。

注意:每次插入树时都会有一个键作为单词,并自动以出现1作为数据开始。插入相同的单词会增加出现次数。

删除功能:

public RedBlackTree<E> remove(String c)
{
    // find the target node - the node whose value is removed
    RedBlackTree<E> target = locate(c);
    if (target.isEmpty()) return root();

    // determine the node to be disconnected:
    // two cases: if degree < 2 we remove target node;
    //            otherwise, remove predecessor
    RedBlackTree<E> freeNode;
    if (target.left().isEmpty() ||
        target.right().isEmpty()) // simply re-root tree at right
    {
        // < two children: target node is easily freed
        freeNode = target;
    } else {
        // two children: find predecessor
        freeNode = target.left();
        while (!freeNode.right().isEmpty())
        {
            freeNode = freeNode.right();
        }
        // freeNode is predecessor
    }

    target.key = freeNode.key; // move value reference

    // child will be orphaned by the freeing of freeNode;
    // reparent this child carefully (it may be EMPTY)
    RedBlackTree<E> child;
    if (freeNode.left().isEmpty())
    {
        child = freeNode.right();
    } else {
        child = freeNode.left();
    }

    // if child is empty, we need to set its parent, temporarily
    child.setParent(freeNode.parent());
    if (!freeNode.isRoot())
    {
        if (freeNode.isLeftChild())
        {
            freeNode.parent().setLeft(child);
        } else {
            freeNode.parent().setRight(child);
        }
    }

    // Assertion: child has been reparented
    RedBlackTree<E> result = child.root();  
    if (freeNode.isBlack()) child.blackFixup();
    return result.root();
}

协助功能:

public RedBlackTree(String v)
{
    key = v;
    data = 1;
    parent = null;
    left = right = new RedBlackTree<E>();
    isRed = false;  // roots of tree should be colored black
}

public boolean isEmpty()
{
    return key == null;
}

protected RedBlackTree<E> locate(String c)
{
    if (isEmpty()) return null;
    int relation = c.compareTo(value());
    if (relation == 0) return this;
    if (relation < 0) return left().locate(c);
    else return right().locate(c);
}

public RedBlackTree<E> add(String c)
{
    RedBlackTree<E> tree = insert(c);  // first, do a plain insert
    tree.setRed();  // we insert nodes as red nodes - a first guess
    tree.redFixup();  // now, rebalance the tree
    return tree.root();  // return new root
}

protected RedBlackTree<E> insert(String c)
{
    // trivial case - tree was empty:
    if (isEmpty()) return new RedBlackTree<E>(c);

    //System.out.println(locate(c));
    if (!key.equals(c)) {

        // decide to insert value to left or right of root:
        if (c.compareTo(value()) < 0) {

            // if to left and no left child, we insert value as leaf 
            if (left().isEmpty()) {
                RedBlackTree<E> result = new RedBlackTree<E>(c);
                setLeft(result);
                return result;
            } else {
                // recursively insert to left
                return left().insert(c);
            }
        } else {

            // if to right and no left child, we insert value as leaf
            if (right().isEmpty()) {
                RedBlackTree<E> result = new RedBlackTree<E>(c);
                setRight(result);
                return result;
            } else {
                // recursively insert to right
                return right().insert(c);
            }
        }
    } else {
        data++;
        return this;
    }
}

0 个答案:

没有答案