コード例 #1
0
ファイル: Node.java プロジェクト: ReadyTalk/revori
  public static void validate(@Nullable Node original, Node n) {
    if (original != null) {
      validate(null, original);
    }

    if (Null.red) {
      trouble(original, n, new RuntimeException("red null!"));
    }

    if (Null.left != Null || Null.right != Null || Null.value != Null || Null.key != null) {
      trouble(original, n, new RuntimeException("corrupted null!"));
    }

    if (n.red) {
      trouble(original, n, new RuntimeException("red root!"));
    }

    NodeStack s = new NodeStack();
    int blackCount = -1;
    for (NodeIterator it = new NodeIterator(s, n); it.hasNext(); ) {
      int index = it.stack.index;
      Node x = it.next();

      if (x.key instanceof Node) {
        trouble(original, n, new RuntimeException("node key!"));
      }

      if (x.key == null) {
        trouble(original, n, new RuntimeException("null key!"));
      }

      if (x.value instanceof Node) {
        validate(original, (Node) x.value);
      }

      if (x.red && (x.left.red || x.right.red)) {
        trouble(original, n, new RuntimeException("red node has red child(ren)!"));
      }

      if (x.left == Node.Null && x.right == Node.Null) {
        int count = 0;
        for (int i = 0; i < index; ++i) {
          if (!s.array[i].red) {
            ++count;
          }
        }
        if (!x.red) {
          ++count;
        }

        if (blackCount == -1) {
          blackCount = count;
        } else if (count != blackCount) {
          trouble(
              original,
              n,
              new RuntimeException("inconsistent number of black nodes per paths to leaves!"));
        }
      }
    }
  }
コード例 #2
0
ファイル: Node.java プロジェクト: ReadyTalk/revori
  public static Node blaze(
      BlazeResult result,
      Object token,
      NodeStack stack,
      Node root,
      Object key,
      Comparator comparator) {
    if (key == null) throw new NullPointerException();

    if (root == null) {
      root = Null;
    }

    if (Debug) {
      token = new Object();
      validate(null, root);
    }

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

    Node old = root;
    Node new_ = newRoot;
    while (old != Null) {
      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 {
        result.node = new_;
        stack.popStack();
        if (Debug) {
          validate(root, newRoot);
        }
        return newRoot;
      }
    }

    new_.key = key;
    result.node = new_;

    // rebalance
    new_.red = true;

    while (stack.top != null && stack.top.red) {
      if (stack.top == stack.peek().left) {
        if (stack.peek().right.red) {
          stack.top.red = false;
          stack.peek().right = getNode(token, stack.peek().right);
          stack.peek().right.red = false;
          stack.peek().red = true;
          new_ = stack.peek();
          stack.pop(2);
        } else {
          if (new_ == stack.top.right) {
            new_ = stack.top;
            stack.pop();

            Node n = leftRotate(token, new_);
            if (stack.top.right == new_) {
              stack.top.right = n;
            } else {
              stack.top.left = n;
            }
            stack.push(n);
          }
          stack.top.red = false;
          stack.peek().red = true;

          Node n = rightRotate(token, stack.peek());
          if (stack.index <= stack.base + 1) {
            newRoot = n;
          } else if (stack.peek(1).right == stack.peek()) {
            stack.peek(1).right = n;
          } else {
            stack.peek(1).left = n;
          }
          // done
        }
      } else {
        // this is just the above code with left and right swapped:
        if (stack.peek().left.red) {
          stack.top.red = false;
          stack.peek().left = getNode(token, stack.peek().left);
          stack.peek().left.red = false;
          stack.peek().red = true;
          new_ = stack.peek();
          stack.pop(2);
        } else {
          if (new_ == stack.top.left) {
            new_ = stack.top;
            stack.pop();

            Node n = rightRotate(token, new_);
            if (stack.top.right == new_) {
              stack.top.right = n;
            } else {
              stack.top.left = n;
            }
            stack.push(n);
          }
          stack.top.red = false;
          stack.peek().red = true;

          Node n = leftRotate(token, stack.peek());
          if (stack.index <= stack.base + 1) {
            newRoot = n;
          } else if (stack.peek(1).right == stack.peek()) {
            stack.peek(1).right = n;
          } else {
            stack.peek(1).left = n;
          }
          // done
        }
      }
    }

    newRoot.red = false;

    stack.popStack();
    if (Debug) {
      validate(root, newRoot);
    }
    return newRoot;
  }
コード例 #3
0
ファイル: Node.java プロジェクト: ReadyTalk/revori
  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;
  }