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.
245 lines
6.3 KiB
245 lines
6.3 KiB
Properties of a rbtree
|
|
======================
|
|
|
|
1. A node is either red or black.
|
|
2. The root is black. (This rule is sometimes omitted. Since the root can
|
|
always be changed from red to black, but not necessarily vice-versa,
|
|
this rule has little effect on analysis.)
|
|
3. All leaves (NIL) are black. (All leaves are same color as the
|
|
root.)
|
|
4. Every red node must have two black child nodes.
|
|
5. Every simple path from a given node to any of its
|
|
descendant leaves contains the same number of black nodes.
|
|
|
|
|
|
Assumptions in addition to wikipedia
|
|
====================================
|
|
|
|
lets assume that NULL pointer are black B nodes. But we mark them with a (N)
|
|
|
|
|
|
Example
|
|
=======
|
|
|
|
we start with the tree from the insert example
|
|
----------------------------------------------
|
|
|
|
B(11)
|
|
|
|
R(8) R(13)
|
|
|
|
B(3) B(9) B(12) B(16)
|
|
|
|
B(N) B(N) B(N) R(10) B(N) B(N) B(N) B(N)
|
|
|
|
B(N) B(N)
|
|
|
|
we remove R(10) / remove a red node (replace with its child):
|
|
wikipedia explains why this can only happen with two leaf children (our B(N))
|
|
|
|
B(11)
|
|
|
|
R(8) R(13)
|
|
|
|
B(3) B(9) B(12) B(16)
|
|
|
|
B(N) B(N) B(N) B(N) B(N) B(N) B(N) B(N)
|
|
|
|
|
|
again start with the insert example result
|
|
------------------------------------------
|
|
|
|
B(11)
|
|
|
|
R(8) R(13)
|
|
|
|
B(3) B(9) B(12) B(16)
|
|
|
|
B(N) B(N) B(N) R(10) B(N) B(N) B(N) B(N)
|
|
|
|
B(N) B(N)
|
|
|
|
remove B(9) (which is the second simple case described on wikipedia)
|
|
M black, C red
|
|
After remove just repaint child black. As I do not replace the node,
|
|
but the value this is simplified in my case to simply do nothing after
|
|
normal delete... :D
|
|
|
|
B(11)
|
|
|
|
R(8) R(13)
|
|
|
|
B(3) B(10) B(12) B(16)
|
|
|
|
B(N) B(N) B(N) B(N) B(N) B(N) B(N) B(N)
|
|
|
|
|
|
again start with the insert example result
|
|
------------------------------------------
|
|
|
|
B(11)
|
|
|
|
R(8) R(13)
|
|
|
|
B(3) B(9) B(12) B(16)
|
|
|
|
B(N) B(N) B(N) R(10) B(N) B(N) B(N) B(N)
|
|
|
|
B(N) B(N)
|
|
|
|
now lets delete B(3)... which is stated on wikipedia as the complicated case
|
|
where 6 subcases could be distinguished.
|
|
|
|
Wikipedia says we begin with replacing B(3) which one if its childs, in my
|
|
case this means, setting r(8)->left to NULL....
|
|
|
|
B(11)
|
|
|
|
R(8) R(13)
|
|
|
|
B(N) B(9) B(12) B(16)
|
|
|
|
B(N) R(10) B(N) B(N) B(N) B(N)
|
|
|
|
B(N) B(N)
|
|
|
|
So, what is called in on Wikipedia is simply a nullpointer for me...hopefully
|
|
I don't have to do anything with it.
|
|
|
|
Get an overview over our variables now:
|
|
|
|
N : Nullpointer set in R(8)->left (thus N will be black by definition, ever)
|
|
P : R(8)
|
|
S : B(9)
|
|
Sl: Nullpointer
|
|
Sr: R(10)
|
|
|
|
cases:
|
|
- case 2: S is red => reverse color of P and S, then rotate left at P
|
|
- case 3: P, S and S's children are black => repaint S red
|
|
- case 4: S and S's children are black, P is red => exchange colors of S and
|
|
P
|
|
- case 5: S and Sr black, Sl is red N left of P => rotate right at S, exchange
|
|
colors of S and Sl
|
|
- case 6: S black, Sr is red N left of P => rotate left at P, exchange colors
|
|
of P and S and make Sr black
|
|
|
|
looks like case 6:
|
|
|
|
first rotate left at P
|
|
|
|
B(11)
|
|
|
|
B(9) R(13)
|
|
|
|
R(8) R(10) B(12) B(16)
|
|
|
|
B(N) B(N) B(N) B(N) B(N) B(N) B(N) B(N)
|
|
|
|
exchange colors of P and S and make Sr black.
|
|
|
|
B(11)
|
|
|
|
R(9) R(13)
|
|
|
|
B(8) B(10) B(12) B(16)
|
|
|
|
B(N) B(N) B(N) B(N) B(N) B(N) B(N) B(N)
|
|
|
|
|
|
|
|
now for case 2, we delete 16 from the following tree
|
|
|
|
B(13)
|
|
|
|
R(8) B(16)
|
|
|
|
B(3) B(11) B(N) B(N)
|
|
|
|
B(N) B(N) R(9) B(N)
|
|
|
|
B(N) B(N)
|
|
|
|
again first lets see what we have where...
|
|
|
|
N : Nullpointer set in R(13)->right (thus N will be black by definition, ever)
|
|
P : B(13)
|
|
S : R(8)
|
|
Sl: B(3)
|
|
Sr: B(11)
|
|
|
|
B(13)P
|
|
|
|
R(8)S B(N)N
|
|
|
|
B(3)Sl B(11)Sr
|
|
|
|
B(N) B(N) R(9) B(N)
|
|
|
|
B(N) B(N)
|
|
|
|
revert colors of P and S
|
|
|
|
R(13)P
|
|
|
|
B(8)S B(N)N
|
|
|
|
B(3)Sl B(11)Sr
|
|
|
|
B(N) B(N) R(9) B(N)
|
|
|
|
B(N) B(N)
|
|
|
|
rotate right at P
|
|
|
|
B(8)S
|
|
|
|
B(3)Sl R(13)P
|
|
|
|
B(N) B(N) B(11)Sr B(N)N
|
|
|
|
R(9) B(N)
|
|
|
|
B(N) B(N)
|
|
|
|
relable ... done on wikipedia (don't know if I will need it.)
|
|
|
|
B(8)
|
|
|
|
B(3) R(13)P
|
|
|
|
B(N) B(N) B(11)S B(N)N
|
|
|
|
R(9)Sl B(N)Sr
|
|
|
|
B(N) B(N)
|
|
|
|
ok, not case 3... P is red
|
|
nor is it case 4 Sl is red.
|
|
kind of case 6 reversed ... lets try what they do in the code not in the description...
|
|
|
|
Sl to black
|
|
|
|
B(8)
|
|
|
|
B(3) R(13)P
|
|
|
|
B(N) B(N) B(11)S B(N)N
|
|
|
|
B(9)Sl B(N)Sr
|
|
|
|
B(N) B(N)
|
|
|
|
rotate right on P
|
|
|
|
B(8)
|
|
|
|
B(3) B(11)S
|
|
|
|
B(N) B(N) B(9)Sl R(13)P
|
|
|
|
B(N) B(N) B(N)Sr B(N)N
|
|
|
|
This result is wrong....the balance is ok, but the color of 9 is wrong.
|
|
|
|
# vim: set et ts=4:
|