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!")); } } } }