From efc60e98d7c948f4297129544c57b480c8d7c9bb Mon Sep 17 00:00:00 2001 From: Matej Focko Date: Sat, 10 Jun 2023 18:04:33 +0200 Subject: [PATCH] =?UTF-8?q?ib002(rb-trees):=20add=20=E2=80=9Cdiscourse?= =?UTF-8?q?=E2=80=9D=20on=20the=20rules?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matej Focko --- ib002/08-rb-trees/rules.md | 262 ++++++++++++++++++ static/files/ib002/rb-trees/rules/rb.dot | 47 ++++ .../files/ib002/rb-trees/rules/rb_height.dot | 47 ++++ .../rules/red-node-black-children/correct.dot | 34 +++ .../red-node-black-children/incorrect.dot | 40 +++ .../ib002/rb-trees/rules/red-root/br_0.dot | 7 + .../ib002/rb-trees/rules/red-root/br_1.dot | 11 + .../ib002/rb-trees/rules/red-root/br_2.dot | 15 + .../ib002/rb-trees/rules/red-root/br_3.dot | 19 ++ .../ib002/rb-trees/rules/red-root/br_4.dot | 23 ++ .../ib002/rb-trees/rules/red-root/br_5.dot | 27 ++ .../ib002/rb-trees/rules/red-root/br_6.dot | 31 +++ .../ib002/rb-trees/rules/red-root/br_7.dot | 35 +++ .../ib002/rb-trees/rules/red-root/br_8.dot | 39 +++ .../ib002/rb-trees/rules/red-root/rr_0.dot | 7 + .../ib002/rb-trees/rules/red-root/rr_1.dot | 11 + .../ib002/rb-trees/rules/red-root/rr_2.dot | 15 + .../ib002/rb-trees/rules/red-root/rr_3.dot | 19 ++ .../ib002/rb-trees/rules/red-root/rr_4.dot | 23 ++ .../ib002/rb-trees/rules/red-root/rr_5.dot | 27 ++ .../ib002/rb-trees/rules/red-root/rr_6.dot | 31 +++ .../ib002/rb-trees/rules/red-root/rr_7.dot | 35 +++ .../ib002/rb-trees/rules/red-root/rr_8.dot | 39 +++ 23 files changed, 844 insertions(+) create mode 100644 ib002/08-rb-trees/rules.md create mode 100644 static/files/ib002/rb-trees/rules/rb.dot create mode 100644 static/files/ib002/rb-trees/rules/rb_height.dot create mode 100644 static/files/ib002/rb-trees/rules/red-node-black-children/correct.dot create mode 100644 static/files/ib002/rb-trees/rules/red-node-black-children/incorrect.dot create mode 100644 static/files/ib002/rb-trees/rules/red-root/br_0.dot create mode 100644 static/files/ib002/rb-trees/rules/red-root/br_1.dot create mode 100644 static/files/ib002/rb-trees/rules/red-root/br_2.dot create mode 100644 static/files/ib002/rb-trees/rules/red-root/br_3.dot create mode 100644 static/files/ib002/rb-trees/rules/red-root/br_4.dot create mode 100644 static/files/ib002/rb-trees/rules/red-root/br_5.dot create mode 100644 static/files/ib002/rb-trees/rules/red-root/br_6.dot create mode 100644 static/files/ib002/rb-trees/rules/red-root/br_7.dot create mode 100644 static/files/ib002/rb-trees/rules/red-root/br_8.dot create mode 100644 static/files/ib002/rb-trees/rules/red-root/rr_0.dot create mode 100644 static/files/ib002/rb-trees/rules/red-root/rr_1.dot create mode 100644 static/files/ib002/rb-trees/rules/red-root/rr_2.dot create mode 100644 static/files/ib002/rb-trees/rules/red-root/rr_3.dot create mode 100644 static/files/ib002/rb-trees/rules/red-root/rr_4.dot create mode 100644 static/files/ib002/rb-trees/rules/red-root/rr_5.dot create mode 100644 static/files/ib002/rb-trees/rules/red-root/rr_6.dot create mode 100644 static/files/ib002/rb-trees/rules/red-root/rr_7.dot create mode 100644 static/files/ib002/rb-trees/rules/red-root/rr_8.dot diff --git a/ib002/08-rb-trees/rules.md b/ib002/08-rb-trees/rules.md new file mode 100644 index 0000000..e6387ce --- /dev/null +++ b/ib002/08-rb-trees/rules.md @@ -0,0 +1,262 @@ +--- +title: On the rules of the red-black tree +description: | + Shower thoughts on the rules of the red-black tree. +tags: +- red-black trees +- balanced trees +--- + +## Introduction + +Have you ever thought about the red-black tree rules in more depth? Why are they +formulated the way they are? How come they keep the tree balanced? Let's go through +each of the red-black tree rules and try to change, break and contemplate about +them. + +We expect that you are familiar with the following set of the rules[^1]: +1. Every node is either red or black. +2. The root is black. +3. Every leaf (`nil`) is black. +4. If a node is red, then both its children are black. +5. For each node, all simple paths from the node to descendant leaves contain the + same number of black nodes. + +Each section will go into _reasonable_ details of each rule. + +## 1ª Every node is either red or black. + +OK… This one is very simple. It is just a definition and is used in all other +rules. Not much to talk about here. Or is there? + +### Do I really need the nodes to be explicitly colored? + +The answer is no. Balancing of the red-black trees is “enforced” by the 4th and +5th rule in the enumeration above. There are many ways you can avoid using colors. + +#### Black height + +We mentioned the 4th and 5th rule and that it enforces the balancing. What does +it mean for us? + +Well, we definitely do not have to use the colors, which even as a _boolean_ flag +would take at least 1 byte of space (and usually even more), cause… well, it is +easier for the CPU to work with words rather than single bits. + +We could use the black height, couldn't we? It would mean more memory used, cause +it should be ideally big and unsigned. Can we tell the color of a node from the +black height? Of course we can, if my child has the same black height as I do, +it means that there was no black node added on the path between us and therefore +my child would be colored red. + +Example of a red-black tree that keeps count of black nodes on paths to the +leaves follows: + +![Red-black tree with black height](/files/ib002/rb-trees/rules/rb_height_light.svg#gh-light-mode-only)![Red-black tree with black height](/files/ib002/rb-trees/rules/rb_height_dark.svg#gh-dark-mode-only) + +We mark the _black heights_ in superscript. You can see that all leaves have the +black height equal to $1$. Let's take a look at some of the interesting cases: + +* If we take a look at the node with $\text{key} = 9$, we can see that it is + coloured red and its black height is 1, because it is a leaf. + + Let's look at its parent (node with $\text{key} = 8$). On its left side it has + `nil` and on its right side the $9$. And its black height is still $1$, cause + except for the `nil` leaves, there are no other black nodes. + + We can clearly see that if a node has the same black height as its parent, it + is a red node. + +* Now let's take a look at the root with $\text{key} = 3$. It has a black height + of 3. Both of its children are black nodes and have black height of 2. + + We can see that if a node has its height 1 lower than its parent, it is a black + node. + + The reasoning behind it is rather simple, we count the black nodes all the way + to the leaves, therefore if my parent has a higher black height, it means that + on the path from me to my parent there is a black node, but the only node added + is me, therefore I must be black. + +#### Isomorphic trees + +One of the other ways to avoid using color is storing the red-black tree in some +isomorphic tree. The structure of 2-3-4 tree allows us to avoid using the color +completely. This is a bit different approach, cause we would be basically using +different tree, so we keep this note in just as a “hack”. + +## 2ª The root is black. + +This rule might seem like a very important one, but overall is not. You can safely +omit this rule, but you also need to deal with the consequences. + +Let's refresh our memory with the algorithm of _insert fixup_: +``` +WHILE z.p.color == Red + IF z.p == z.p.p.left + y = z.p.p.right + + IF y.color == Red + z.p.color = Black + y.color = Black + z.p.p.color = Red + z = z.p.p + ELSE + IF z == z.p.right + z = z.p + Left-Rotate(T, z) + z.p.color = Black + z.p.p.color = Red + Right-Rotate(T, z.p.p) + ELSE (same as above with “right” and “left” exchanged) + +T.root.color = Black +``` + +:::tip + +If you have tried to implement any of the more complex data structures, such as +red-black trees, etc., in a statically typed language that also checks you for +`NULL`-correctness (e.g. _mypy_ or even C# with nullable reference types), you +might have run into numerous issues in the cases where you are 100% sure that you +cannot obtain `NULL` because of the invariants, but the static type checking +doesn't know that. + +The issue we hit with the _insert fixup_ is very similar. + +::: + +You might not realize the issue at the first sight, but the algorithm described +with the pseudocode above expects that the root of the red-black tree is black by +both relying on the invariant in the algorithm and afterwards by enforcing the +black root property. + +If we decide to omit this condition, we need to address it in the pseudocodes +accordingly. + +| Usual algorithm with black root | Allowing red root | +| :-----------------------------: | :---------------: | +| ![1ª insertion](/files/ib002/rb-trees/rules/red-root/br_0_light.svg#gh-light-mode-only)![1ª insertion](/files/ib002/rb-trees/rules/red-root/br_0_dark.svg#gh-dark-mode-only) | ![1ª insertion](/files/ib002/rb-trees/rules/red-root/rr_0_light.svg#gh-light-mode-only)![1ª insertion](/files/ib002/rb-trees/rules/red-root/rr_0_dark.svg#gh-dark-mode-only) | +| ![2ª insertion](/files/ib002/rb-trees/rules/red-root/br_1_light.svg#gh-light-mode-only)![2ª insertion](/files/ib002/rb-trees/rules/red-root/br_1_dark.svg#gh-dark-mode-only) | ![2ª insertion](/files/ib002/rb-trees/rules/red-root/rr_1_light.svg#gh-light-mode-only)![2ª insertion](/files/ib002/rb-trees/rules/red-root/rr_1_dark.svg#gh-dark-mode-only) | +| ![3ª insertion](/files/ib002/rb-trees/rules/red-root/br_2_light.svg#gh-light-mode-only)![3ª insertion](/files/ib002/rb-trees/rules/red-root/br_2_dark.svg#gh-dark-mode-only) | ![3ª insertion](/files/ib002/rb-trees/rules/red-root/rr_2_light.svg#gh-light-mode-only)![3ª insertion](/files/ib002/rb-trees/rules/red-root/rr_2_dark.svg#gh-dark-mode-only) | +| ![4ª insertion](/files/ib002/rb-trees/rules/red-root/br_3_light.svg#gh-light-mode-only)![4ª insertion](/files/ib002/rb-trees/rules/red-root/br_3_dark.svg#gh-dark-mode-only) | ![4ª insertion](/files/ib002/rb-trees/rules/red-root/rr_3_light.svg#gh-light-mode-only)![4ª insertion](/files/ib002/rb-trees/rules/red-root/rr_3_dark.svg#gh-dark-mode-only) | +| ![5ª insertion](/files/ib002/rb-trees/rules/red-root/br_4_light.svg#gh-light-mode-only)![5ª insertion](/files/ib002/rb-trees/rules/red-root/br_4_dark.svg#gh-dark-mode-only) | ![5ª insertion](/files/ib002/rb-trees/rules/red-root/rr_4_light.svg#gh-light-mode-only)![5ª insertion](/files/ib002/rb-trees/rules/red-root/rr_4_dark.svg#gh-dark-mode-only) | +| ![6ª insertion](/files/ib002/rb-trees/rules/red-root/br_5_light.svg#gh-light-mode-only)![6ª insertion](/files/ib002/rb-trees/rules/red-root/br_5_dark.svg#gh-dark-mode-only) | ![6ª insertion](/files/ib002/rb-trees/rules/red-root/rr_5_light.svg#gh-light-mode-only)![6ª insertion](/files/ib002/rb-trees/rules/red-root/rr_5_dark.svg#gh-dark-mode-only) | +| ![7ª insertion](/files/ib002/rb-trees/rules/red-root/br_6_light.svg#gh-light-mode-only)![7ª insertion](/files/ib002/rb-trees/rules/red-root/br_6_dark.svg#gh-dark-mode-only) | ![7ª insertion](/files/ib002/rb-trees/rules/red-root/rr_6_light.svg#gh-light-mode-only)![7ª insertion](/files/ib002/rb-trees/rules/red-root/rr_6_dark.svg#gh-dark-mode-only) | +| ![8ª insertion](/files/ib002/rb-trees/rules/red-root/br_7_light.svg#gh-light-mode-only)![8ª insertion](/files/ib002/rb-trees/rules/red-root/br_7_dark.svg#gh-dark-mode-only) | ![8ª insertion](/files/ib002/rb-trees/rules/red-root/rr_7_light.svg#gh-light-mode-only)![8ª insertion](/files/ib002/rb-trees/rules/red-root/rr_7_dark.svg#gh-dark-mode-only) | +| ![9ª insertion](/files/ib002/rb-trees/rules/red-root/br_8_light.svg#gh-light-mode-only)![9ª insertion](/files/ib002/rb-trees/rules/red-root/br_8_dark.svg#gh-dark-mode-only) | ![9ª insertion](/files/ib002/rb-trees/rules/red-root/rr_8_light.svg#gh-light-mode-only)![9ª insertion](/files/ib002/rb-trees/rules/red-root/rr_8_dark.svg#gh-dark-mode-only) | + +## 3ª Every leaf (`nil`) is black. + +Now, this rule is a funny one. What does this imply and can I interpret this in +some other way? Let's go through some of the possible ways I can look at this and +how would they affect the other rules and balancing. + +We will experiment with the following tree: +![Red-black tree](/files/ib002/rb-trees/rules/rb_light.svg#gh-light-mode-only)![Red-black tree](/files/ib002/rb-trees/rules/rb_dark.svg#gh-dark-mode-only) + +We should start by counting the black nodes from root to the `nil` leaves based +on the rules. We have multiple similar paths, so we will pick only the interesting +ones. + +1. What happens if we do not count the `nil` leaves? +2. What happens if we consider leaves the nodes with _no descendants_, i.e. both + of node's children are `nil`? +3. What happens if we do not count the `nil` leaves, but consider nodes with at + least one `nil` descendant as leaves? + +| path | black nodes | 1ª idea | 2ª idea | 3ª idea | +| ------------------------: | ----------: | ------: | ------: | ------: | +| `3 → 1 → 0 → nil` | 4 | 3 | 4 | 3 | +| `3 → 5 → 7 → 8 → nil` | 4 | 3 | - | 3 | +| `3 → 5 → 7 → 8 → 9 → nil` | 4 | 3 | 4 | 3 | + +First idea is very easy to execute and it is also very easy to argue about its +correctness. It is correct, because we just subtract one from each of the paths. +This affects **all** paths and therefore results in global decrease by one. + +Second idea is a bit more complicated. We count the `nil`s, so the count is $4$ +as it should be. However, there is one difference. Second path no longer satisfies +the condition of a _leaf_. Technically it relaxes the 5th rule, because we leave +out some of the nodes. We should probably avoid that. + +:::caution + +With the second idea, you may also feel that we are “bending” the rules a bit, +especially the definition of the “leaf” nodes. + +Given the definition of the red-black tree, where `nil` is considered to be an +external node, we have decided that bending it a bit just to stir a thought about +it won't hurt anybody. :wink: + +::: + +## 4ª If a node is red, then both its children are black. + +This rule might seem rather silly on the first look, but there are 2 important +functions: + +1. it allows the algorithms to _“notice”_ that something went wrong (i.e. the + tree needs to be rebalanced), and +2. it holds the balancing and height of the tree _“in check”_ (with the help of + the 5th rule). + +When we have a look at the algorithms that are used for fixing up the red-black +tree after an insertion or deletion, we will notice that all the algorithms need +is the color of the node. + +> How come it is the only thing that we need? +> How come such naïve thing can be enough? + +Let's say we perform an insertion into the tree… We go with the usual and pretty +primitive insertion into the binary-search tree and then, if needed, we “fix up” +broken invariants. _How can that be enough?_ With each insertion and deletion we +maintain the invariants, therefore if we break them with one operation, there's +only one path on which the invariants were _felled_. If we know that rest of the +tree is correct, it allows us to fix the issues just by propagating it to the +root and _abusing_ the siblings (which are, of course, correct red-black +subtrees) to fix or at least partially mitigate the issues and propagate them +further. + +Let's assume that we do not enforce this rule, you can see how it breaks the +balancing of the tree below. + +| Enforcing this rule | Omitting this rule | +| :-----------------: | :----------------: | +| ![correct](/files/ib002/rb-trees/rules/red-node-black-children/correct_light.svg#gh-light-mode-only)![correct](/files/ib002/rb-trees/rules/red-node-black-children/correct_dark.svg#gh-dark-mode-only) | ![incorrect](/files/ib002/rb-trees/rules/red-node-black-children/incorrect_light.svg#gh-light-mode-only)![incorrect](/files/ib002/rb-trees/rules/red-node-black-children/incorrect_dark.svg#gh-dark-mode-only) | + +We can create a **big** subtree with only red nodes and **even** when keeping +the rest of the rules maintained, it will break the time complexity. It stops us +from “hacking” the black height requirement laid by the 5th rule. + +## 5ª For each node, all simple paths from the node to descendant leaves contain the same number of black nodes. + +As it was mentioned, with the 4th rule they hold the balancing of the red-black +tree. + +:::tip + +An important observation here is the fact that the red-black tree is a +**height**-balanced tree. + +::: + +Enforcing this rule (together with the 4th rule) keeps the tree balanced: +1. 4th rule makes sure we can't “hack” this requirement. +2. This rule ensures that we have “similar”[^2] length to each of the leaves. + +:::tip AVL tree + +You might have heard about an _AVL tree_ before. It is the first self-balanced +tree to be ever introduced and works in a very similar nature as the red-black +tree, the only difference is that it does not deal with the _black height_, but +the height in general. + +If you were to compare AVL with the red-black tree, you can say that AVL is much +more strict while red-black tree can still maintain the same asymptotic time +complexity for the operations, but having more relaxed rules. + +::: + +[^1]: CORMEN, Thomas. Introduction to algorithms. Cambridge, Mass: MIT Press, 2009. isbn 9780262033848. +[^2]: red nodes still exist \ No newline at end of file diff --git a/static/files/ib002/rb-trees/rules/rb.dot b/static/files/ib002/rb-trees/rules/rb.dot new file mode 100644 index 0000000..f494cbc --- /dev/null +++ b/static/files/ib002/rb-trees/rules/rb.dot @@ -0,0 +1,47 @@ +digraph { + "Node(value=3, rank=2)" [label="3"]; #done + "Node(value=1, rank=1)" [label="1"]; #done + "Node(value=4, rank=0)" [label="4"]; #done + "Node(value=7, rank=1)" [label="7", color="red"]; #done + "Node(value=0, rank=0)" [label="0"]; #done + "Node(value=2, rank=0)" [label="2"]; #done + "Node(value=5, rank=1)" [label="5"]; #done + "Node(value=6, rank=0)" [label="6"]; #done + "Node(value=8, rank=0)" [label="8"]; #done + + "nil1" [label="nil"] + "nil2" [label="nil"] + "nil3" [label="nil"] + "nil4" [label="nil"] + "nil5" [label="nil"] + "nil6" [label="nil"] + "nil7" [label="nil"] + "nil8" [label="nil"] + "nil9" [label="nil"] + "nil10" [label="nil"] + "nil11" [label="nil"] + "Node(value=9, rank=0)" [label="9", color="red"]; #done + + "Node(value=3, rank=2)" -> "Node(value=1, rank=1)" #done + "Node(value=1, rank=1)" -> "Node(value=0, rank=0)" #done + "Node(value=1, rank=1)" -> "Node(value=2, rank=0)" #done + "Node(value=3, rank=2)" -> "Node(value=5, rank=1)" #done + "Node(value=5, rank=1)" -> "Node(value=4, rank=0)" #done + "Node(value=5, rank=1)" -> "Node(value=7, rank=1)" [color="red"] #done + "Node(value=7, rank=1)" -> "Node(value=6, rank=0)" #done + "Node(value=7, rank=1)" -> "Node(value=8, rank=0)" #done + + "Node(value=8, rank=0)" -> "nil1" + "Node(value=8, rank=0)" -> "Node(value=9, rank=0)" [color="red"] #done + + "Node(value=0, rank=0)" -> "nil2" + "Node(value=0, rank=0)" -> "nil3" + "Node(value=2, rank=0)" -> "nil4" + "Node(value=2, rank=0)" -> "nil5" + "Node(value=4, rank=0)" -> "nil6" + "Node(value=4, rank=0)" -> "nil7" + "Node(value=6, rank=0)" -> "nil8" + "Node(value=6, rank=0)" -> "nil9" + "Node(value=9, rank=0)" -> "nil10" + "Node(value=9, rank=0)" -> "nil11" +} \ No newline at end of file diff --git a/static/files/ib002/rb-trees/rules/rb_height.dot b/static/files/ib002/rb-trees/rules/rb_height.dot new file mode 100644 index 0000000..034ac64 --- /dev/null +++ b/static/files/ib002/rb-trees/rules/rb_height.dot @@ -0,0 +1,47 @@ +digraph { + "Node(value=3, rank=2)" [label="3⁽³⁾"]; #done + "Node(value=1, rank=1)" [label="1⁽²⁾"]; #done + "Node(value=4, rank=0)" [label="4⁽¹⁾"]; #done + "Node(value=7, rank=1)" [label="7⁽²⁾", color="red"]; #done + "Node(value=0, rank=0)" [label="0⁽¹⁾"]; #done + "Node(value=2, rank=0)" [label="2⁽¹⁾"]; #done + "Node(value=5, rank=1)" [label="5⁽²⁾"]; #done + "Node(value=6, rank=0)" [label="6⁽¹⁾"]; #done + "Node(value=8, rank=0)" [label="8⁽¹⁾"]; #done + + "nil1" [label="nil"] + "nil2" [label="nil"] + "nil3" [label="nil"] + "nil4" [label="nil"] + "nil5" [label="nil"] + "nil6" [label="nil"] + "nil7" [label="nil"] + "nil8" [label="nil"] + "nil9" [label="nil"] + "nil10" [label="nil"] + "nil11" [label="nil"] + "Node(value=9, rank=0)" [label="9⁽¹⁾", color="red"]; #done + + "Node(value=3, rank=2)" -> "Node(value=1, rank=1)" #done + "Node(value=1, rank=1)" -> "Node(value=0, rank=0)" #done + "Node(value=1, rank=1)" -> "Node(value=2, rank=0)" #done + "Node(value=3, rank=2)" -> "Node(value=5, rank=1)" #done + "Node(value=5, rank=1)" -> "Node(value=4, rank=0)" #done + "Node(value=5, rank=1)" -> "Node(value=7, rank=1)" [color="red"] #done + "Node(value=7, rank=1)" -> "Node(value=6, rank=0)" #done + "Node(value=7, rank=1)" -> "Node(value=8, rank=0)" #done + + "Node(value=8, rank=0)" -> "nil1" + "Node(value=8, rank=0)" -> "Node(value=9, rank=0)" [color="red"] #done + + "Node(value=0, rank=0)" -> "nil2" + "Node(value=0, rank=0)" -> "nil3" + "Node(value=2, rank=0)" -> "nil4" + "Node(value=2, rank=0)" -> "nil5" + "Node(value=4, rank=0)" -> "nil6" + "Node(value=4, rank=0)" -> "nil7" + "Node(value=6, rank=0)" -> "nil8" + "Node(value=6, rank=0)" -> "nil9" + "Node(value=9, rank=0)" -> "nil10" + "Node(value=9, rank=0)" -> "nil11" +} \ No newline at end of file diff --git a/static/files/ib002/rb-trees/rules/red-node-black-children/correct.dot b/static/files/ib002/rb-trees/rules/red-node-black-children/correct.dot new file mode 100644 index 0000000..785f4f9 --- /dev/null +++ b/static/files/ib002/rb-trees/rules/red-node-black-children/correct.dot @@ -0,0 +1,34 @@ +digraph { + "Node(value=3, rank=2)" [label="3"]; #done + "Node(value=1, rank=1)" [label="1", color="red"]; #done + "Node(value=4, rank=0)" [label="4", color="red"]; #done + "Node(value=7, rank=0)" [label="7", color="red"]; #done + "Node(value=0, rank=0)" [label="0"]; #done + "Node(value=2, rank=0)" [label="2"]; #done + "Node(value=5, rank=1)" [label="5"]; #done + + "nil2" [label="", color=none] + "nil3" [label="", color=none] + "nil4" [label="", color=none] + "nil5" [label="", color=none] + "nil6" [label="", color=none] + "nil7" [label="", color=none] + "nil8" [label="", color=none] + "nil9" [label="", color=none] + + "Node(value=3, rank=2)" -> "Node(value=1, rank=1)" #done + "Node(value=1, rank=1)" -> "Node(value=0, rank=0)" #done + "Node(value=1, rank=1)" -> "Node(value=2, rank=0)" #done + "Node(value=3, rank=2)" -> "Node(value=5, rank=1)" #done + "Node(value=5, rank=1)" -> "Node(value=4, rank=0)" #done + "Node(value=5, rank=1)" -> "Node(value=7, rank=0)" [color="red"] #done + + "Node(value=0, rank=0)" -> "nil2" + "Node(value=0, rank=0)" -> "nil3" + "Node(value=2, rank=0)" -> "nil4" + "Node(value=2, rank=0)" -> "nil5" + "Node(value=4, rank=0)" -> "nil6" + "Node(value=4, rank=0)" -> "nil7" + "Node(value=7, rank=0)" -> "nil8" + "Node(value=7, rank=0)" -> "nil9" +} \ No newline at end of file diff --git a/static/files/ib002/rb-trees/rules/red-node-black-children/incorrect.dot b/static/files/ib002/rb-trees/rules/red-node-black-children/incorrect.dot new file mode 100644 index 0000000..a2428a0 --- /dev/null +++ b/static/files/ib002/rb-trees/rules/red-node-black-children/incorrect.dot @@ -0,0 +1,40 @@ +digraph { + "Node(value=3, rank=2)" [label="3"]; #done + "Node(value=1, rank=1)" [label="1", color="red"]; #done + "Node(value=4, rank=0)" [label="4", color="red"]; #done + "Node(value=7, rank=0)" [label="7", color="red"]; #done + "Node(value=0, rank=0)" [label="0"]; #done + "Node(value=2, rank=0)" [label="2"]; #done + "Node(value=5, rank=1)" [label="5"]; #done + + + "nil2" [label="", color=none] + "nil3" [label="", color=none] + "nil4" [label="", color=none] + "nil5" [label="", color=none] + "nil6" [label="", color=none] + "nil7" [label="", color=none] + "nil8" [label="", color=none] + "nil9" [label="", color=none] + "nil10" [label="", color=none] + "8" [label="8", color="red"] + + "Node(value=3, rank=2)" -> "Node(value=1, rank=1)" #done + "Node(value=1, rank=1)" -> "Node(value=0, rank=0)" #done + "Node(value=1, rank=1)" -> "Node(value=2, rank=0)" #done + "Node(value=3, rank=2)" -> "Node(value=5, rank=1)" #done + "Node(value=5, rank=1)" -> "Node(value=4, rank=0)" #done + "Node(value=5, rank=1)" -> "Node(value=7, rank=0)" [color="red"] #done + + "Node(value=0, rank=0)" -> "nil2" + "Node(value=0, rank=0)" -> "nil3" + "Node(value=2, rank=0)" -> "nil4" + "Node(value=2, rank=0)" -> "nil5" + "Node(value=4, rank=0)" -> "nil6" + "Node(value=4, rank=0)" -> "nil7" + "Node(value=7, rank=0)" -> "nil8" + "Node(value=7, rank=0)" -> "8" [color="red"] + + "8" -> "nil9" + "8" -> "nil10" +} \ No newline at end of file diff --git a/static/files/ib002/rb-trees/rules/red-root/br_0.dot b/static/files/ib002/rb-trees/rules/red-root/br_0.dot new file mode 100644 index 0000000..8877a45 --- /dev/null +++ b/static/files/ib002/rb-trees/rules/red-root/br_0.dot @@ -0,0 +1,7 @@ +digraph RBTree { +"140399805603280" [label="12"] +L140399805603280 [label="",color=none] +140399805603280 -> L140399805603280 +R140399805603280 [label="",color=none] +140399805603280 -> R140399805603280 +} diff --git a/static/files/ib002/rb-trees/rules/red-root/br_1.dot b/static/files/ib002/rb-trees/rules/red-root/br_1.dot new file mode 100644 index 0000000..c7ff4f0 --- /dev/null +++ b/static/files/ib002/rb-trees/rules/red-root/br_1.dot @@ -0,0 +1,11 @@ +digraph RBTree { +"140399805603280" [label="12"] +"140399805603280" -> "140399804142928" [color="red"] +"140399804142928" [color=red,label="5"] +L140399804142928 [label="",color=none] +140399804142928 -> L140399804142928 +R140399804142928 [label="",color=none] +140399804142928 -> R140399804142928 +R140399805603280 [label="",color=none] +140399805603280 -> R140399805603280 +} diff --git a/static/files/ib002/rb-trees/rules/red-root/br_2.dot b/static/files/ib002/rb-trees/rules/red-root/br_2.dot new file mode 100644 index 0000000..f4387c8 --- /dev/null +++ b/static/files/ib002/rb-trees/rules/red-root/br_2.dot @@ -0,0 +1,15 @@ +digraph RBTree { +"140399805910672" [label="9"] +"140399805910672" -> "140399804142928" [color="red"] +"140399804142928" [color=red,label="5"] +L140399804142928 [label="",color=none] +140399804142928 -> L140399804142928 +R140399804142928 [label="",color=none] +140399804142928 -> R140399804142928 +"140399805910672" -> "140399805603280" [color="red"] +"140399805603280" [color=red,label="12"] +L140399805603280 [label="",color=none] +140399805603280 -> L140399805603280 +R140399805603280 [label="",color=none] +140399805603280 -> R140399805603280 +} diff --git a/static/files/ib002/rb-trees/rules/red-root/br_3.dot b/static/files/ib002/rb-trees/rules/red-root/br_3.dot new file mode 100644 index 0000000..fe0b4f9 --- /dev/null +++ b/static/files/ib002/rb-trees/rules/red-root/br_3.dot @@ -0,0 +1,19 @@ +digraph RBTree { +"140399805910672" [label="9"] +"140399805910672" -> "140399804142928" +"140399804142928" [label="5"] +L140399804142928 [label="",color=none] +140399804142928 -> L140399804142928 +R140399804142928 [label="",color=none] +140399804142928 -> R140399804142928 +"140399805910672" -> "140399805603280" +"140399805603280" [label="12"] +L140399805603280 [label="",color=none] +140399805603280 -> L140399805603280 +"140399805603280" -> "140399805700368" [color="red"] +"140399805700368" [color=red,label="18"] +L140399805700368 [label="",color=none] +140399805700368 -> L140399805700368 +R140399805700368 [label="",color=none] +140399805700368 -> R140399805700368 +} diff --git a/static/files/ib002/rb-trees/rules/red-root/br_4.dot b/static/files/ib002/rb-trees/rules/red-root/br_4.dot new file mode 100644 index 0000000..41ba8e3 --- /dev/null +++ b/static/files/ib002/rb-trees/rules/red-root/br_4.dot @@ -0,0 +1,23 @@ +digraph RBTree { +"140399805910672" [label="9"] +"140399805910672" -> "140399804142928" +"140399804142928" [label="5"] +"140399804142928" -> "140399805700304" [color="red"] +"140399805700304" [color=red,label="2"] +L140399805700304 [label="",color=none] +140399805700304 -> L140399805700304 +R140399805700304 [label="",color=none] +140399805700304 -> R140399805700304 +R140399804142928 [label="",color=none] +140399804142928 -> R140399804142928 +"140399805910672" -> "140399805603280" +"140399805603280" [label="12"] +L140399805603280 [label="",color=none] +140399805603280 -> L140399805603280 +"140399805603280" -> "140399805700368" [color="red"] +"140399805700368" [color=red,label="18"] +L140399805700368 [label="",color=none] +140399805700368 -> L140399805700368 +R140399805700368 [label="",color=none] +140399805700368 -> R140399805700368 +} diff --git a/static/files/ib002/rb-trees/rules/red-root/br_5.dot b/static/files/ib002/rb-trees/rules/red-root/br_5.dot new file mode 100644 index 0000000..61daf82 --- /dev/null +++ b/static/files/ib002/rb-trees/rules/red-root/br_5.dot @@ -0,0 +1,27 @@ +digraph RBTree { +"140399805910672" [label="9"] +"140399805910672" -> "140399804142928" +"140399804142928" [label="5"] +"140399804142928" -> "140399805700304" [color="red"] +"140399805700304" [color=red,label="2"] +L140399805700304 [label="",color=none] +140399805700304 -> L140399805700304 +R140399805700304 [label="",color=none] +140399805700304 -> R140399805700304 +R140399804142928 [label="",color=none] +140399804142928 -> R140399804142928 +"140399805910672" -> "140399805605392" +"140399805605392" [label="15"] +"140399805605392" -> "140399805603280" [color="red"] +"140399805603280" [color=red,label="12"] +L140399805603280 [label="",color=none] +140399805603280 -> L140399805603280 +R140399805603280 [label="",color=none] +140399805603280 -> R140399805603280 +"140399805605392" -> "140399805700368" [color="red"] +"140399805700368" [color=red,label="18"] +L140399805700368 [label="",color=none] +140399805700368 -> L140399805700368 +R140399805700368 [label="",color=none] +140399805700368 -> R140399805700368 +} diff --git a/static/files/ib002/rb-trees/rules/red-root/br_6.dot b/static/files/ib002/rb-trees/rules/red-root/br_6.dot new file mode 100644 index 0000000..89720ef --- /dev/null +++ b/static/files/ib002/rb-trees/rules/red-root/br_6.dot @@ -0,0 +1,31 @@ +digraph RBTree { +"140399805910672" [label="9"] +"140399805910672" -> "140399804142928" +"140399804142928" [label="5"] +"140399804142928" -> "140399805700304" [color="red"] +"140399805700304" [color=red,label="2"] +L140399805700304 [label="",color=none] +140399805700304 -> L140399805700304 +R140399805700304 [label="",color=none] +140399805700304 -> R140399805700304 +R140399804142928 [label="",color=none] +140399804142928 -> R140399804142928 +"140399805910672" -> "140399805605392" [color="red"] +"140399805605392" [color=red,label="15"] +"140399805605392" -> "140399805603280" +"140399805603280" [label="12"] +L140399805603280 [label="",color=none] +140399805603280 -> L140399805603280 +"140399805603280" -> "140399805605456" [color="red"] +"140399805605456" [color=red,label="13"] +L140399805605456 [label="",color=none] +140399805605456 -> L140399805605456 +R140399805605456 [label="",color=none] +140399805605456 -> R140399805605456 +"140399805605392" -> "140399805700368" +"140399805700368" [label="18"] +L140399805700368 [label="",color=none] +140399805700368 -> L140399805700368 +R140399805700368 [label="",color=none] +140399805700368 -> R140399805700368 +} diff --git a/static/files/ib002/rb-trees/rules/red-root/br_7.dot b/static/files/ib002/rb-trees/rules/red-root/br_7.dot new file mode 100644 index 0000000..21514cd --- /dev/null +++ b/static/files/ib002/rb-trees/rules/red-root/br_7.dot @@ -0,0 +1,35 @@ +digraph RBTree { +"140399805910672" [label="9"] +"140399805910672" -> "140399804142928" +"140399804142928" [label="5"] +"140399804142928" -> "140399805700304" [color="red"] +"140399805700304" [color=red,label="2"] +L140399805700304 [label="",color=none] +140399805700304 -> L140399805700304 +R140399805700304 [label="",color=none] +140399805700304 -> R140399805700304 +R140399804142928 [label="",color=none] +140399804142928 -> R140399804142928 +"140399805910672" -> "140399805605392" [color="red"] +"140399805605392" [color=red,label="15"] +"140399805605392" -> "140399805603280" +"140399805603280" [label="12"] +L140399805603280 [label="",color=none] +140399805603280 -> L140399805603280 +"140399805603280" -> "140399805605456" [color="red"] +"140399805605456" [color=red,label="13"] +L140399805605456 [label="",color=none] +140399805605456 -> L140399805605456 +R140399805605456 [label="",color=none] +140399805605456 -> R140399805605456 +"140399805605392" -> "140399805700368" +"140399805700368" [label="18"] +L140399805700368 [label="",color=none] +140399805700368 -> L140399805700368 +"140399805700368" -> "140399805605584" [color="red"] +"140399805605584" [color=red,label="19"] +L140399805605584 [label="",color=none] +140399805605584 -> L140399805605584 +R140399805605584 [label="",color=none] +140399805605584 -> R140399805605584 +} diff --git a/static/files/ib002/rb-trees/rules/red-root/br_8.dot b/static/files/ib002/rb-trees/rules/red-root/br_8.dot new file mode 100644 index 0000000..d025321 --- /dev/null +++ b/static/files/ib002/rb-trees/rules/red-root/br_8.dot @@ -0,0 +1,39 @@ +digraph RBTree { +"140399805910672" [label="9"] +"140399805910672" -> "140399804142928" +"140399804142928" [label="5"] +"140399804142928" -> "140399805700304" [color="red"] +"140399805700304" [color=red,label="2"] +L140399805700304 [label="",color=none] +140399805700304 -> L140399805700304 +R140399805700304 [label="",color=none] +140399805700304 -> R140399805700304 +R140399804142928 [label="",color=none] +140399804142928 -> R140399804142928 +"140399805910672" -> "140399805605392" [color="red"] +"140399805605392" [color=red,label="15"] +"140399805605392" -> "140399805603280" +"140399805603280" [label="12"] +L140399805603280 [label="",color=none] +140399805603280 -> L140399805603280 +"140399805603280" -> "140399805605456" [color="red"] +"140399805605456" [color=red,label="13"] +L140399805605456 [label="",color=none] +140399805605456 -> L140399805605456 +R140399805605456 [label="",color=none] +140399805605456 -> R140399805605456 +"140399805605392" -> "140399805700368" +"140399805700368" [label="18"] +"140399805700368" -> "140399804318928" [color="red"] +"140399804318928" [color=red,label="17"] +L140399804318928 [label="",color=none] +140399804318928 -> L140399804318928 +R140399804318928 [label="",color=none] +140399804318928 -> R140399804318928 +"140399805700368" -> "140399805605584" [color="red"] +"140399805605584" [color=red,label="19"] +L140399805605584 [label="",color=none] +140399805605584 -> L140399805605584 +R140399805605584 [label="",color=none] +140399805605584 -> R140399805605584 +} diff --git a/static/files/ib002/rb-trees/rules/red-root/rr_0.dot b/static/files/ib002/rb-trees/rules/red-root/rr_0.dot new file mode 100644 index 0000000..2827711 --- /dev/null +++ b/static/files/ib002/rb-trees/rules/red-root/rr_0.dot @@ -0,0 +1,7 @@ +digraph RBTree { +"139660435791312" [color=red,label="12"] +L139660435791312 [label="",color=none] +139660435791312 -> L139660435791312 +R139660435791312 [label="",color=none] +139660435791312 -> R139660435791312 +} diff --git a/static/files/ib002/rb-trees/rules/red-root/rr_1.dot b/static/files/ib002/rb-trees/rules/red-root/rr_1.dot new file mode 100644 index 0000000..4dcbf83 --- /dev/null +++ b/static/files/ib002/rb-trees/rules/red-root/rr_1.dot @@ -0,0 +1,11 @@ +digraph RBTree { +"139660435791312" [label="12"] +"139660435791312" -> "139660436098128" [color="red"] +"139660436098128" [color=red,label="5"] +L139660436098128 [label="",color=none] +139660436098128 -> L139660436098128 +R139660436098128 [label="",color=none] +139660436098128 -> R139660436098128 +R139660435791312 [label="",color=none] +139660435791312 -> R139660435791312 +} diff --git a/static/files/ib002/rb-trees/rules/red-root/rr_2.dot b/static/files/ib002/rb-trees/rules/red-root/rr_2.dot new file mode 100644 index 0000000..c79d728 --- /dev/null +++ b/static/files/ib002/rb-trees/rules/red-root/rr_2.dot @@ -0,0 +1,15 @@ +digraph RBTree { +"139660434247376" [label="9"] +"139660434247376" -> "139660436098128" [color="red"] +"139660436098128" [color=red,label="5"] +L139660436098128 [label="",color=none] +139660436098128 -> L139660436098128 +R139660436098128 [label="",color=none] +139660436098128 -> R139660436098128 +"139660434247376" -> "139660435791312" [color="red"] +"139660435791312" [color=red,label="12"] +L139660435791312 [label="",color=none] +139660435791312 -> L139660435791312 +R139660435791312 [label="",color=none] +139660435791312 -> R139660435791312 +} diff --git a/static/files/ib002/rb-trees/rules/red-root/rr_3.dot b/static/files/ib002/rb-trees/rules/red-root/rr_3.dot new file mode 100644 index 0000000..d0396a0 --- /dev/null +++ b/static/files/ib002/rb-trees/rules/red-root/rr_3.dot @@ -0,0 +1,19 @@ +digraph RBTree { +"139660434247376" [color=red,label="9"] +"139660434247376" -> "139660436098128" +"139660436098128" [label="5"] +L139660436098128 [label="",color=none] +139660436098128 -> L139660436098128 +R139660436098128 [label="",color=none] +139660436098128 -> R139660436098128 +"139660434247376" -> "139660435791312" +"139660435791312" [label="12"] +L139660435791312 [label="",color=none] +139660435791312 -> L139660435791312 +"139660435791312" -> "139660435887824" [color="red"] +"139660435887824" [color=red,label="18"] +L139660435887824 [label="",color=none] +139660435887824 -> L139660435887824 +R139660435887824 [label="",color=none] +139660435887824 -> R139660435887824 +} diff --git a/static/files/ib002/rb-trees/rules/red-root/rr_4.dot b/static/files/ib002/rb-trees/rules/red-root/rr_4.dot new file mode 100644 index 0000000..da78acd --- /dev/null +++ b/static/files/ib002/rb-trees/rules/red-root/rr_4.dot @@ -0,0 +1,23 @@ +digraph RBTree { +"139660434247376" [color=red,label="9"] +"139660434247376" -> "139660436098128" +"139660436098128" [label="5"] +"139660436098128" -> "139660435887760" [color="red"] +"139660435887760" [color=red,label="2"] +L139660435887760 [label="",color=none] +139660435887760 -> L139660435887760 +R139660435887760 [label="",color=none] +139660435887760 -> R139660435887760 +R139660436098128 [label="",color=none] +139660436098128 -> R139660436098128 +"139660434247376" -> "139660435791312" +"139660435791312" [label="12"] +L139660435791312 [label="",color=none] +139660435791312 -> L139660435791312 +"139660435791312" -> "139660435887824" [color="red"] +"139660435887824" [color=red,label="18"] +L139660435887824 [label="",color=none] +139660435887824 -> L139660435887824 +R139660435887824 [label="",color=none] +139660435887824 -> R139660435887824 +} diff --git a/static/files/ib002/rb-trees/rules/red-root/rr_5.dot b/static/files/ib002/rb-trees/rules/red-root/rr_5.dot new file mode 100644 index 0000000..753579b --- /dev/null +++ b/static/files/ib002/rb-trees/rules/red-root/rr_5.dot @@ -0,0 +1,27 @@ +digraph RBTree { +"139660434247376" [color=red,label="9"] +"139660434247376" -> "139660436098128" +"139660436098128" [label="5"] +"139660436098128" -> "139660435887760" [color="red"] +"139660435887760" [color=red,label="2"] +L139660435887760 [label="",color=none] +139660435887760 -> L139660435887760 +R139660435887760 [label="",color=none] +139660435887760 -> R139660435887760 +R139660436098128 [label="",color=none] +139660436098128 -> R139660436098128 +"139660434247376" -> "139660435793424" +"139660435793424" [label="15"] +"139660435793424" -> "139660435791312" [color="red"] +"139660435791312" [color=red,label="12"] +L139660435791312 [label="",color=none] +139660435791312 -> L139660435791312 +R139660435791312 [label="",color=none] +139660435791312 -> R139660435791312 +"139660435793424" -> "139660435887824" [color="red"] +"139660435887824" [color=red,label="18"] +L139660435887824 [label="",color=none] +139660435887824 -> L139660435887824 +R139660435887824 [label="",color=none] +139660435887824 -> R139660435887824 +} diff --git a/static/files/ib002/rb-trees/rules/red-root/rr_6.dot b/static/files/ib002/rb-trees/rules/red-root/rr_6.dot new file mode 100644 index 0000000..984fab5 --- /dev/null +++ b/static/files/ib002/rb-trees/rules/red-root/rr_6.dot @@ -0,0 +1,31 @@ +digraph RBTree { +"139660434247376" [label="9"] +"139660434247376" -> "139660436098128" +"139660436098128" [label="5"] +"139660436098128" -> "139660435887760" [color="red"] +"139660435887760" [color=red,label="2"] +L139660435887760 [label="",color=none] +139660435887760 -> L139660435887760 +R139660435887760 [label="",color=none] +139660435887760 -> R139660435887760 +R139660436098128 [label="",color=none] +139660436098128 -> R139660436098128 +"139660434247376" -> "139660435793424" [color="red"] +"139660435793424" [color=red,label="15"] +"139660435793424" -> "139660435791312" +"139660435791312" [label="12"] +L139660435791312 [label="",color=none] +139660435791312 -> L139660435791312 +"139660435791312" -> "139660435793488" [color="red"] +"139660435793488" [color=red,label="13"] +L139660435793488 [label="",color=none] +139660435793488 -> L139660435793488 +R139660435793488 [label="",color=none] +139660435793488 -> R139660435793488 +"139660435793424" -> "139660435887824" +"139660435887824" [label="18"] +L139660435887824 [label="",color=none] +139660435887824 -> L139660435887824 +R139660435887824 [label="",color=none] +139660435887824 -> R139660435887824 +} diff --git a/static/files/ib002/rb-trees/rules/red-root/rr_7.dot b/static/files/ib002/rb-trees/rules/red-root/rr_7.dot new file mode 100644 index 0000000..09f51a3 --- /dev/null +++ b/static/files/ib002/rb-trees/rules/red-root/rr_7.dot @@ -0,0 +1,35 @@ +digraph RBTree { +"139660434247376" [label="9"] +"139660434247376" -> "139660436098128" +"139660436098128" [label="5"] +"139660436098128" -> "139660435887760" [color="red"] +"139660435887760" [color=red,label="2"] +L139660435887760 [label="",color=none] +139660435887760 -> L139660435887760 +R139660435887760 [label="",color=none] +139660435887760 -> R139660435887760 +R139660436098128 [label="",color=none] +139660436098128 -> R139660436098128 +"139660434247376" -> "139660435793424" [color="red"] +"139660435793424" [color=red,label="15"] +"139660435793424" -> "139660435791312" +"139660435791312" [label="12"] +L139660435791312 [label="",color=none] +139660435791312 -> L139660435791312 +"139660435791312" -> "139660435793488" [color="red"] +"139660435793488" [color=red,label="13"] +L139660435793488 [label="",color=none] +139660435793488 -> L139660435793488 +R139660435793488 [label="",color=none] +139660435793488 -> R139660435793488 +"139660435793424" -> "139660435887824" +"139660435887824" [label="18"] +L139660435887824 [label="",color=none] +139660435887824 -> L139660435887824 +"139660435887824" -> "139660435793616" [color="red"] +"139660435793616" [color=red,label="19"] +L139660435793616 [label="",color=none] +139660435793616 -> L139660435793616 +R139660435793616 [label="",color=none] +139660435793616 -> R139660435793616 +} diff --git a/static/files/ib002/rb-trees/rules/red-root/rr_8.dot b/static/files/ib002/rb-trees/rules/red-root/rr_8.dot new file mode 100644 index 0000000..33f6023 --- /dev/null +++ b/static/files/ib002/rb-trees/rules/red-root/rr_8.dot @@ -0,0 +1,39 @@ +digraph RBTree { +"139660434247376" [label="9"] +"139660434247376" -> "139660436098128" +"139660436098128" [label="5"] +"139660436098128" -> "139660435887760" [color="red"] +"139660435887760" [color=red,label="2"] +L139660435887760 [label="",color=none] +139660435887760 -> L139660435887760 +R139660435887760 [label="",color=none] +139660435887760 -> R139660435887760 +R139660436098128 [label="",color=none] +139660436098128 -> R139660436098128 +"139660434247376" -> "139660435793424" [color="red"] +"139660435793424" [color=red,label="15"] +"139660435793424" -> "139660435791312" +"139660435791312" [label="12"] +L139660435791312 [label="",color=none] +139660435791312 -> L139660435791312 +"139660435791312" -> "139660435793488" [color="red"] +"139660435793488" [color=red,label="13"] +L139660435793488 [label="",color=none] +139660435793488 -> L139660435793488 +R139660435793488 [label="",color=none] +139660435793488 -> R139660435793488 +"139660435793424" -> "139660435887824" +"139660435887824" [label="18"] +"139660435887824" -> "139660434506512" [color="red"] +"139660434506512" [color=red,label="17"] +L139660434506512 [label="",color=none] +139660434506512 -> L139660434506512 +R139660434506512 [label="",color=none] +139660434506512 -> R139660434506512 +"139660435887824" -> "139660435793616" [color="red"] +"139660435793616" [color=red,label="19"] +L139660435793616 [label="",color=none] +139660435793616 -> L139660435793616 +R139660435793616 [label="",color=none] +139660435793616 -> R139660435793616 +}