You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
4.8 KiB
144 lines
4.8 KiB
// 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");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|