public void test1() { StringRedBlackTree tree = new StringRedBlackTree(5); Assert.Equal(0, tree.getSizeInBytes()); checkTree(tree); Assert.Equal(0, tree.add("owen")); checkTree(tree); Assert.Equal(1, tree.add("ashutosh")); checkTree(tree); Assert.Equal(0, tree.add("owen")); checkTree(tree); Assert.Equal(2, tree.add("alan")); checkTree(tree); Assert.Equal(2, tree.add("alan")); checkTree(tree); Assert.Equal(1, tree.add("ashutosh")); checkTree(tree); Assert.Equal(3, tree.add("greg")); checkTree(tree); Assert.Equal(4, tree.add("eric")); checkTree(tree); Assert.Equal(5, tree.add("arun")); checkTree(tree); Assert.Equal(6, tree.Size); checkTree(tree); Assert.Equal(6, tree.add("eric14")); checkTree(tree); Assert.Equal(7, tree.add("o")); checkTree(tree); Assert.Equal(8, tree.add("ziggy")); checkTree(tree); Assert.Equal(9, tree.add("z")); checkTree(tree); checkContents(tree, new int[] { 2, 5, 1, 4, 6, 3, 7, 0, 9, 8 }, "alan", "arun", "ashutosh", "eric", "eric14", "greg", "o", "owen", "z", "ziggy"); Assert.Equal(32888, tree.getSizeInBytes()); // check that adding greg again bumps the count Assert.Equal(3, tree.add("greg")); Assert.Equal(41, tree.getCharacterSize()); // add some more strings to test the different branches of the // rebalancing Assert.Equal(10, tree.add("zak")); checkTree(tree); Assert.Equal(11, tree.add("eric1")); checkTree(tree); Assert.Equal(12, tree.add("ash")); checkTree(tree); Assert.Equal(13, tree.add("harry")); checkTree(tree); Assert.Equal(14, tree.add("john")); checkTree(tree); tree.clear(); checkTree(tree); Assert.Equal(0, tree.getSizeInBytes()); Assert.Equal(0, tree.getCharacterSize()); }
/** * Checks the red-black tree rules to make sure that we have correctly built * a valid tree. * * Properties: * 1. Red nodes must have black children * 2. Each node must have the same black height on both sides. * * @param node The id of the root of the subtree to check for the red-black * tree properties. * @return The black-height of the subtree. */ private int checkSubtree(StringRedBlackTree tree, int node, ref int count) { if (node == StringRedBlackTree.NULL) { return(1); } count++; bool is_red = tree.isRed(node); int left = tree.getLeft(node); int right = tree.getRight(node); if (is_red) { if (tree.isRed(left)) { printTree(tree, "", tree.Root); throw new InvalidOperationException("Left node of " + node + " is " + left + " and both are red."); } if (tree.isRed(right)) { printTree(tree, "", tree.Root); throw new InvalidOperationException("Right node of " + node + " is " + right + " and both are red."); } } int left_depth = checkSubtree(tree, left, ref count); int right_depth = checkSubtree(tree, right, ref count); if (left_depth != right_depth) { printTree(tree, "", tree.Root); throw new InvalidOperationException("Lopsided tree at node " + node + " with depths " + left_depth + " and " + right_depth); } if (is_red) { return(left_depth); } else { return(left_depth + 1); } }
void checkContents(StringRedBlackTree tree, int[] order, params string[] values) { tree.visit(new MyVisitor(values, order)); }
public void visit(StringRedBlackTree.VisitorContext context) { context.writeBytes(writer.stringOutput); writer.lengthOutput.write(context.getLength()); dumpOrder[context.getOriginalPosition()] = currentId++; }
public void visit(StringRedBlackTree.VisitorContext context) { string word = context.getText().ToString(); Assert.Equal(words[current], word); Assert.Equal(order[current], context.getOriginalPosition()); buffer.Position = 0; buffer.SetLength(0); context.writeBytes(buffer); Assert.Equal(word, Encoding.UTF8.GetString(buffer.ToArray())); current += 1; }
void printTree(StringRedBlackTree tree, string indent, int node) { if (node == StringRedBlackTree.NULL) { System.Console.Error.WriteLine(indent + "NULL"); } else { System.Console.Error.WriteLine(indent + "Node " + node + " color " + (tree.isRed(node) ? "red" : "black")); printTree(tree, indent + " ", tree.getLeft(node)); printTree(tree, indent + " ", tree.getRight(node)); } }
/** * Checks the validity of the entire tree. Also ensures that the number of * nodes visited is the same as the size of the set. */ void checkTree(StringRedBlackTree tree) { int count = 0; if (tree.isRed(tree.Root)) { printTree(tree, "", tree.Root); throw new InvalidOperationException("root is red"); } checkSubtree(tree, tree.Root, ref count); if (count != tree.Size) { printTree(tree, "", tree.Root); throw new InvalidOperationException("Broken tree! visited= " + count + " size=" + tree.Size); } }
/** * Checks the red-black tree rules to make sure that we have correctly built * a valid tree. * * Properties: * 1. Red nodes must have black children * 2. Each node must have the same black height on both sides. * * @param node The id of the root of the subtree to check for the red-black * tree properties. * @return The black-height of the subtree. */ private int checkSubtree(StringRedBlackTree tree, int node, ref int count) { if (node == StringRedBlackTree.NULL) { return 1; } count++; bool is_red = tree.isRed(node); int left = tree.getLeft(node); int right = tree.getRight(node); if (is_red) { if (tree.isRed(left)) { printTree(tree, "", tree.Root); throw new InvalidOperationException("Left node of " + node + " is " + left + " and both are red."); } if (tree.isRed(right)) { printTree(tree, "", tree.Root); throw new InvalidOperationException("Right node of " + node + " is " + right + " and both are red."); } } int left_depth = checkSubtree(tree, left, ref count); int right_depth = checkSubtree(tree, right, ref count); if (left_depth != right_depth) { printTree(tree, "", tree.Root); throw new InvalidOperationException("Lopsided tree at node " + node + " with depths " + left_depth + " and " + right_depth); } if (is_red) { return left_depth; } else { return left_depth + 1; } }
StringRedBlackTree buildTree(params string[] values) { StringRedBlackTree result = new StringRedBlackTree(1000); foreach (string word in values) { result.add(word); checkTree(result); } return result; }