|
|
// RBTree.java
import java.io.FileWriter; import java.io.IOException;
class RBTree<T extends Comparable<T>> {
private static final boolean RED = true; private static final boolean BLACK = false; private static int step = 0;
private class Node { T key; Node left, right; boolean color;
Node(T key, boolean color) { this.key = key; this.color = color; } }
private Node root;
public void insert(T key) { root = insert(root, key); root.color = BLACK; // Ensure the root is always black
}
private Node insert(Node root, T key) { if (root == null) { return new Node(key, RED); // New nodes are always red
}
int cmp = key.compareTo(root.key); if (cmp < 0) { root.left = insert(root.left, key); } else if (cmp > 0) { root.right = insert(root.right, key); } else { // Duplicate key, do not insert
return root; }
// Fix any Red-Black tree violations
if (isRed(root.right) && !isRed(root.left)) { root = rotateLeft(root); } if (isRed(root.left) && isRed(root.left.left)) { root = rotateRight(root); } if (isRed(root.left) && isRed(root.right)) { flipColors(root); }
return root; // Return the updated root
}
private boolean isRed(Node node) { if (node == null) { return false; } return node.color == RED; }
private Node rotateLeft(Node h) { Node x = h.right; h.right = x.left; x.left = h; x.color = h.color; h.color = RED; return x; }
private Node rotateRight(Node h) { Node x = h.left; h.left = x.right; x.right = h; x.color = h.color; h.color = RED; return x; }
private void flipColors(Node h) { h.color = RED; h.left.color = BLACK; h.right.color = BLACK; }
public void printDOTAfterInsert(String filename, T key) { try (FileWriter writer = new FileWriter(filename)) { writer.write("digraph G {\n"); writer.write("\tgraph [ratio=.48];\n"); writer.write("\tnode [style=filled, color=black, shape=circle, width=.6 \n"); writer.write("\t\tfontname=Helvetica, fontweight=bold, fontcolor=white, \n"); writer.write("\t\tfontsize=24, fixedsize=true];\n"); root = insert(root, key); // Füge das Element ein und aktualisiere den Baum
printDOTRecursive(root, writer); writer.write("}\n"); } catch (IOException e) { e.printStackTrace(); } }
private void printDOTRecursive(Node node, FileWriter writer) throws IOException { if (node != null) { String keyString = node.key.toString().replaceAll("[^a-zA-Z0-9]", "_"); // Ersetze ungültige Zeichen
// Setze Farben basierend auf der Rot-Schwarz-Eigenschaft
String fillColor = (node.color == RED) ? "red" : "black"; String fontColor = (node.color == RED) ? "white" : "white"; // Ändern Sie dies, wenn Sie schwarzen Text auf rotem Hintergrund möchten
// Print current node mit Farbinformationen
writer.write("\t\"" + keyString + "\" [fillcolor=" + fillColor + ", fontcolor=" + fontColor + "];\n"); // Print left child
if (node.left != null) { String leftKeyString = node.left.key.toString().replaceAll("[^a-zA-Z0-9]", "_"); writer.write("\t\"" + keyString + "\" -> \"" + leftKeyString + "\";\n"); printDOTRecursive(node.left, writer); } else { // Füge ein NIL-Blatt für leere linke Zweige hinzu
String leftNilKeyString = keyString + "_NIL_L"; writer.write("\t\"" + leftNilKeyString + "\" [shape=plaintext, label=\"NIL\", fontsize=16];\n"); writer.write("\t\"" + keyString + "\" -> \"" + leftNilKeyString + "\";\n"); } // Print right child
if (node.right != null) { String rightKeyString = node.right.key.toString().replaceAll("[^a-zA-Z0-9]", "_"); writer.write("\t\"" + keyString + "\" -> \"" + rightKeyString + "\";\n"); printDOTRecursive(node.right, writer); } else { // Füge ein NIL-Blatt für leere rechte Zweige hinzu
String rightNilKeyString = keyString + "_NIL_R"; writer.write("\t\"" + rightNilKeyString + "\" [shape=plaintext, label=\"NIL\", fontsize=16];\n"); writer.write("\t\"" + keyString + "\" -> \"" + rightNilKeyString + "\";\n"); } } } }
|