deathkid535
deathkid535

Reputation: 3

Properly deleting a node in a Ternary Search Tree

I want to delete a specific node using a key from a Ternary Search Tree. This works pretty well in most cases, but in some of my test sets, nodes that do not have a middle child also do not store values, which shouldn't happen.

I tried different methods I found online, but pretty much all of those few leave the tree in a dirty state, which makes searching a hassle, since you need to check if the leaf you found actually has a value, which shouldn't happen.

Here is my relevant code

private boolean hasChildren(Node x) {
    return (x.left != null || x.mid != null || x.right != null);
}

private void reHang(Node x) {
    if (hasChildren(x)) {
        if (x.left != null) {
            x.parent.mid = x.left;
            x.left.right = x.right;
        } else if (x.right != null) {
            x.parent.mid = x.right;
        }
    }
}

private boolean remove(Node x, String key, int d) {
  if (x == null) return false;
  char c = key.charAt(d);
  if (c < x.c) {
      if (!remove(x.left, key, d)) {
          x.left = null;
      }
  } else if (c > x.c) {
      if (!remove(x.right, key, d)) {
          x.right = null;
      }
  } else if (d < key.length() - 1) {
      if (!remove(x.mid, key, d + 1)) {
          x.mid = null;
          if (x.val != null) return true;
      }
  } else {
      x.val = null;
  }

  reHang(x);
  return hasChildren(x);
}

private class Node
{
    private Value val;
    private char c;
    private Node left, mid, right, parent;
}

Specifically, problems occur in this function I use for prefix lookups:

private Node getMidPath(Node x) {
    if (x.left != null) return getMidPath(x.left);
    if (x.mid == null) return x;
    return getMidPath(x.mid);
}

Every Node that does not have a x.mid should have an x.val set, which is not always the case after remove, meaning I have dirty nodes.

Any help would be greatly appreciated.

Upvotes: 0

Views: 700

Answers (1)

Lee
Lee

Reputation: 1427

You must see a ternary tree at was it is: Some nested Binary tree but witch each level have only on character as key instead of the whole string. Go down you binary trees until you string is exhausted. Here you will have two eventually references one to the actual data and and one two the actual subtree for longer string with same prefix. Now set the data to null. When the subtree reference is null remove the node. When now the entire subtree is empty continue with the subtree one character earlier. Here set subtree reference to null. Now is both references are null remove the node. When now the entire subtree is empty continue with the subtree one character earlier. And so on

Upvotes: 0

Related Questions