0

I am trying to implement a red-black tree in Java and my remove() function is having an issue where it's throwing a NullPointerException.

First off, I create a root and insert to my red-black tree like so:

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

Then I have a GUI where I can choose to remove a certain node using the word. For some reason, I must manually insert into the r-b tree the same word that I want to delete. (By the way, the insert function increments a word occurrence variable and just add's one two the node's data value. So every node has a unique word.) After I insert, I can remove it without a NullPointerException. But if I just try to remove the word before I manually insert, it will throw an exception. Even though the word is in the tree based on my insert() function the tree seems to not find it.

Note: Every insertion to the tree has a key which is the word, and automatically starts with an occurrence of 1 as the data. Inserting the same word will increment the occurrence.

Remove function:

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();
}

Assisting functions:

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;
    }
}
Erwin Bolwidt
  • 30,799
  • 15
  • 56
  • 79
  • Possible duplicate of [What is a Null Pointer Exception, and how do I fix it?](http://stackoverflow.com/questions/218384/what-is-a-null-pointer-exception-and-how-do-i-fix-it) – Erwin Bolwidt Dec 10 '15 at 06:15
  • I know what a NullPointer is and why it's happening. But I'm lost when it comes to fixing it. –  Dec 10 '15 at 06:16
  • ... "and how do I fix it?" !!! – Erwin Bolwidt Dec 10 '15 at 06:16
  • The nodes when I load the tree are added the same way they are manually when I do through the gui. But for some reason they're not found. –  Dec 10 '15 at 06:19

0 Answers0