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 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); } }
/** * 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; } }