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

  1. // RBTree.java
  2. import java.io.FileWriter;
  3. import java.io.IOException;
  4. class RBTree<T extends Comparable<T>> {
  5. private static final boolean RED = true;
  6. private static final boolean BLACK = false;
  7. private static int step = 0;
  8. private class Node {
  9. T key;
  10. Node left, right;
  11. boolean color;
  12. Node(T key, boolean color) {
  13. this.key = key;
  14. this.color = color;
  15. }
  16. }
  17. private Node root;
  18. public void insert(T key) {
  19. root = insert(root, key);
  20. root.color = BLACK; // Ensure the root is always black
  21. }
  22. private Node insert(Node root, T key) {
  23. if (root == null) {
  24. return new Node(key, RED); // New nodes are always red
  25. }
  26. int cmp = key.compareTo(root.key);
  27. if (cmp < 0) {
  28. root.left = insert(root.left, key);
  29. } else if (cmp > 0) {
  30. root.right = insert(root.right, key);
  31. } else {
  32. // Duplicate key, do not insert
  33. return root;
  34. }
  35. // Fix any Red-Black tree violations
  36. if (isRed(root.right) && !isRed(root.left)) {
  37. root = rotateLeft(root);
  38. }
  39. if (isRed(root.left) && isRed(root.left.left)) {
  40. root = rotateRight(root);
  41. }
  42. if (isRed(root.left) && isRed(root.right)) {
  43. flipColors(root);
  44. }
  45. return root; // Return the updated root
  46. }
  47. private boolean isRed(Node node) {
  48. if (node == null) {
  49. return false;
  50. }
  51. return node.color == RED;
  52. }
  53. private Node rotateLeft(Node h) {
  54. Node x = h.right;
  55. h.right = x.left;
  56. x.left = h;
  57. x.color = h.color;
  58. h.color = RED;
  59. return x;
  60. }
  61. private Node rotateRight(Node h) {
  62. Node x = h.left;
  63. h.left = x.right;
  64. x.right = h;
  65. x.color = h.color;
  66. h.color = RED;
  67. return x;
  68. }
  69. private void flipColors(Node h) {
  70. h.color = RED;
  71. h.left.color = BLACK;
  72. h.right.color = BLACK;
  73. }
  74. public void printDOTAfterInsert(String filename, T key) {
  75. try (FileWriter writer = new FileWriter(filename)) {
  76. writer.write("digraph G {\n");
  77. writer.write("\tgraph [ratio=.48];\n");
  78. writer.write("\tnode [style=filled, color=black, shape=circle, width=.6 \n");
  79. writer.write("\t\tfontname=Helvetica, fontweight=bold, fontcolor=white, \n");
  80. writer.write("\t\tfontsize=24, fixedsize=true];\n");
  81. root = insert(root, key); // Füge das Element ein und aktualisiere den Baum
  82. printDOTRecursive(root, writer);
  83. writer.write("}\n");
  84. } catch (IOException e) {
  85. e.printStackTrace();
  86. }
  87. }
  88. private void printDOTRecursive(Node node, FileWriter writer) throws IOException {
  89. if (node != null) {
  90. String keyString = node.key.toString().replaceAll("[^a-zA-Z0-9]", "_"); // Ersetze ungültige Zeichen
  91. // Setze Farben basierend auf der Rot-Schwarz-Eigenschaft
  92. String fillColor = (node.color == RED) ? "red" : "black";
  93. String fontColor = (node.color == RED) ? "white" : "white"; // Ändern Sie dies, wenn Sie schwarzen Text auf rotem Hintergrund möchten
  94. // Print current node mit Farbinformationen
  95. writer.write("\t\"" + keyString + "\" [fillcolor=" + fillColor + ", fontcolor=" + fontColor + "];\n");
  96. // Print left child
  97. if (node.left != null) {
  98. String leftKeyString = node.left.key.toString().replaceAll("[^a-zA-Z0-9]", "_");
  99. writer.write("\t\"" + keyString + "\" -> \"" + leftKeyString + "\";\n");
  100. printDOTRecursive(node.left, writer);
  101. } else {
  102. // Füge ein NIL-Blatt für leere linke Zweige hinzu
  103. String leftNilKeyString = keyString + "_NIL_L";
  104. writer.write("\t\"" + leftNilKeyString + "\" [shape=plaintext, label=\"NIL\", fontsize=16];\n");
  105. writer.write("\t\"" + keyString + "\" -> \"" + leftNilKeyString + "\";\n");
  106. }
  107. // Print right child
  108. if (node.right != null) {
  109. String rightKeyString = node.right.key.toString().replaceAll("[^a-zA-Z0-9]", "_");
  110. writer.write("\t\"" + keyString + "\" -> \"" + rightKeyString + "\";\n");
  111. printDOTRecursive(node.right, writer);
  112. } else {
  113. // Füge ein NIL-Blatt für leere rechte Zweige hinzu
  114. String rightNilKeyString = keyString + "_NIL_R";
  115. writer.write("\t\"" + rightNilKeyString + "\" [shape=plaintext, label=\"NIL\", fontsize=16];\n");
  116. writer.write("\t\"" + keyString + "\" -> \"" + rightNilKeyString + "\";\n");
  117. }
  118. }
  119. }
  120. }