Exemple #1
0
  public static Node delete(
      Object token, NodeStack stack, Node root, Object key, Comparator comparator) {
    if (Debug) {
      token = new Object();
      validate(null, root);
    }

    if (root == Null) {
      return root;
    } else if (root.left == Null && root.right == Null) {
      if (Compare.equal(key, root.key, comparator)) {
        return Null;
      } else {
        return root;
      }
    }

    stack = new NodeStack(stack);
    Node newRoot = getNode(token, root);

    Node old = root;
    Node new_ = newRoot;
    while (old != Null) {
      if (key == null) throw new NullPointerException();
      if (old.key == null) {
        throw new NullPointerException();
      }
      int difference = Compare.compare(key, old.key, comparator);
      if (difference < 0) {
        stack.push(new_);
        old = old.left;
        new_ = new_.left = getNode(token, old);
      } else if (difference > 0) {
        stack.push(new_);
        old = old.right;
        new_ = new_.right = getNode(token, old);
      } else {
        break;
      }
    }

    if (old == Null) {
      if (stack.top.left == new_) {
        stack.top.left = Null;
      } else {
        stack.top.right = Null;
      }
      stack.popStack();
      return root;
    }

    Node dead;
    if (new_.left == Null || new_.right == Null) {
      dead = new_;
    } else {
      successor(token, new_, stack);
      dead = stack.top;
      stack.pop();
    }

    Node child;
    if (dead.left != Null) {
      child = getNode(token, dead.left);
    } else if (dead.right != Null) {
      child = getNode(token, dead.right);
    } else {
      child = Null;
    }

    if (stack.top == null) {
      child.red = false;
      stack.popStack();
      if (Debug) {
        validate(root, child);
      }
      return child;
    } else if (dead == stack.top.left) {
      stack.top.left = child;
    } else {
      stack.top.right = child;
    }

    if (dead != new_) {
      new_.key = dead.key;
      new_.value = dead.value;
    }

    if (!dead.red) {
      // rebalance
      while (stack.top != null && !child.red) {
        if (Debug) checkArgument(stack.top.token == token);
        if (child == stack.top.left) {
          Node sibling = stack.top.right = getNode(token, stack.top.right);
          if (sibling.red) {
            if (Debug) checkArgument(sibling.token == token);
            sibling.red = false;
            stack.top.red = true;

            Node n = leftRotate(token, stack.top);
            if (stack.index == stack.base) {
              newRoot = n;
            } else if (stack.peek().right == stack.top) {
              if (Debug) checkArgument(stack.peek().token == token);
              stack.peek().right = n;
            } else {
              if (Debug) checkArgument(stack.peek().token == token);
              stack.peek().left = n;
            }
            Node parent = stack.top;
            stack.top = n;
            stack.push(parent);

            sibling = stack.top.right = getNode(token, stack.top.right);
          }

          if (!(sibling.left.red || sibling.right.red)) {
            if (Debug) checkArgument(sibling.token == token);
            sibling.red = true;
            child = stack.top;
            stack.pop();
          } else {
            if (!sibling.right.red) {
              sibling.left = getNode(token, sibling.left);
              sibling.left.red = false;

              if (Debug) checkArgument(sibling.token == token);
              sibling.red = true;
              sibling = stack.top.right = rightRotate(token, sibling);
            }

            if (Debug) checkArgument(sibling.token == token);
            sibling.red = stack.top.red;
            stack.top.red = false;

            sibling.right = getNode(token, sibling.right);
            sibling.right.red = false;

            Node n = leftRotate(token, stack.top);
            if (stack.index == stack.base) {
              newRoot = n;
            } else if (stack.peek().right == stack.top) {
              if (Debug) checkArgument(stack.peek().token == token);
              stack.peek().right = n;
            } else {
              if (Debug) checkArgument(stack.peek().token == token);
              stack.peek().left = n;
            }

            child = newRoot;
            stack.clear();
          }
        } else {
          // this is just the above code with left and right swapped:
          Node sibling = stack.top.left = getNode(token, stack.top.left);
          if (sibling.red) {
            if (Debug) checkArgument(sibling.token == token);
            sibling.red = false;
            stack.top.red = true;

            Node n = rightRotate(token, stack.top);
            if (stack.index == stack.base) {
              newRoot = n;
            } else if (stack.peek().left == stack.top) {
              if (Debug) checkArgument(stack.peek().token == token);
              stack.peek().left = n;
            } else {
              if (Debug) checkArgument(stack.peek().token == token);
              stack.peek().right = n;
            }
            Node parent = stack.top;
            stack.top = n;
            stack.push(parent);

            sibling = stack.top.left = getNode(token, stack.top.left);
          }

          if (!(sibling.right.red || sibling.left.red)) {
            if (Debug) checkArgument(sibling.token == token);
            sibling.red = true;
            child = stack.top;
            stack.pop();
          } else {
            if (!sibling.left.red) {
              sibling.right = getNode(token, sibling.right);
              sibling.right.red = false;

              if (Debug) checkArgument(sibling.token == token);
              sibling.red = true;
              sibling = stack.top.left = leftRotate(token, sibling);
            }

            if (Debug) checkArgument(sibling.token == token);
            sibling.red = stack.top.red;
            stack.top.red = false;

            sibling.left = getNode(token, sibling.left);
            sibling.left.red = false;

            Node n = rightRotate(token, stack.top);
            if (stack.index == stack.base) {
              newRoot = n;
            } else if (stack.peek().left == stack.top) {
              if (Debug) checkArgument(stack.peek().token == token);
              stack.peek().left = n;
            } else {
              if (Debug) checkArgument(stack.peek().token == token);
              stack.peek().right = n;
            }

            child = newRoot;
            stack.clear();
          }
        }
      }

      if (Debug) checkArgument(child.token == token);
      child.red = false;
    }

    stack.popStack();
    if (Debug) {
      validate(root, newRoot);
    }
    return newRoot;
  }
Exemple #2
0
 static {
   Null.left = Null;
   Null.right = Null;
   Null.value = Null;
 }