' B) b7 C, ? S+ S( C9 s2 K* v1 s def rb_rotate_left(self,node):0 _, ^3 u9 ~7 i8 D! c
right=node.right $ O$ x2 J3 z% w0 p5 W& z, L2 n+ E+ ?2 e! `" n9 e: t
node.right=right.left . i6 c- I# G l- d6 p if node.right is not None:$ N/ P2 W2 F* E0 W7 j- L
right.left.parent=node1 x2 W& L, A! k/ _
& G" N2 W' v6 e9 I: |1 H right.left=node$ W% U( {" d. u1 Q1 |( y" i; E6 g
right.parent=node.parent % ]; u& V4 H6 _5 c0 v( v' s. k3 s) ? R/ B% k5 B' \& A
if right.parent is None:) v3 W5 i& h+ J" ]8 e9 h7 Y T6 F
7 Q' X+ Z. h4 p4 j+ F3 R3 d; D self.root=right % [# R# e& L3 ~6 J else: 9 g! E% x2 R, X) P. L! G if node==node.parent.right:1 b! N1 U, i0 K2 u! O5 J( U) I, [- ~
node.parent.right=right % m7 j1 H; p) h- e# Z$ D7 p else:3 O& b4 `7 Q2 e) R
node.parent.left=right , s; h+ E: E1 t* M" k& v node.parent =right7 g5 O/ G6 L$ }0 d
* Q2 o& S- E3 B# g( d, ~/ Q+ o
8 K6 g I8 E8 `9 e8 g' R# A* y def rb_rotate_right(self,node):( t0 O* t, c' M2 R/ a
left=node.left * A0 ^, `6 K9 J8 d- Y& ~1 N node.left=left.right$ s* T% c0 A/ r2 f- I, e
; e6 Q- h2 W* n. t
if node.left is not None: 7 z+ }; P1 E- z/ J$ r; y1 d3 N left.right.parent=node : \* \2 Y; r e" p ~& C1 k$ T0 S% r9 B/ W9 M! |
left.right=node( V9 @5 @" s/ e O# r$ ]
left.parent=node.parent $ u4 H" j3 J1 ~" [) p& s5 x( i5 H7 t7 {; b* h
if left.parent is None:7 I' w( H# M. p& r- r3 I
self.root=left9 N9 k J* p& k
else:) @9 i1 X( A5 o2 t
if node==node.parent.right: 2 }5 A$ n' k( o! O- X node.parent.right=left K- P! z) R9 `( ^ else:9 q9 U; K/ t+ {' f6 `- C! t# N
node.parent.left=left % Q6 k* L/ E7 X& S8 K" K node.parent=left ! |3 R' O; z, r- O+ ]& E% G: X3 l& O& g0 D
def rb_insert_rebalance(self,node): . V( |% ]. `1 p parent=node.parent & z* X0 Z& D( R7 m5 d while parent and parent.color==RED:. v8 N G, c$ R( c" s- {: M4 G, r
gparent = parent.parent % @- w' i, A4 p5 S8 f5 R3 e if parent==gparent.left:9 J3 ~2 [* `$ s% H- T0 c0 u [$ h
uncle=gparent.right+ }9 B" N# b$ |% S- O# L4 _ B
if uncle and uncle.color==RED:8 a( ~5 C2 F2 a
uncle.color=BLACK6 A$ X; g8 K7 Y q% o
parent.color=BLACK( [. }$ c0 e1 L# S" I n
gparent.color=RED * J1 n; G( F: k0 L" a q- L node=gparent4 O j% R3 |4 Y5 i4 a8 q
else:5 x8 b% m k8 @. b0 _% F* K
if parent.right==node:: \- V$ a. {& M
self.rb_rotate_left(parent)' h2 r) ]7 v. y
tmp=parent 0 A3 ~. {/ v' g parent=node ) H6 E8 T9 ]( Q: {* f+ W$ E7 t node=tmp& P6 N# w2 ]' ~) D0 \0 v
parent.color=BLACK. H% C$ w# e5 ?6 Z1 ^% b$ L3 G; _' T
gparent.color=RED* ^% q: R: V, P3 _7 d2 P% j
E9 Z9 f+ h* l! N# z* F5 k self.rb_rotate_right(gparent) 6 F% B/ W5 ]8 ?: E# G( i+ p4 l' Y0 u" |3 w0 t0 P y
if uncle:* H# ?1 R+ e9 j W9 [ {
if uncle.right:# m* T* Y( A% q3 N# _8 H9 _; \
node=uncle.right % U, s( |8 ~2 l P else: : H( t/ x! ?# D# S2 w uncle=gparent.left ) q6 n+ G# _3 M6 C+ J+ A6 d if uncle and uncle.color==RED: ! Z, W) P* t, i# a) o uncle.color=BLACK 7 p; E+ c' b. v parent.color=BLACK % J2 a9 \1 K6 \. f) v/ r9 g+ L gparent.color=RED / }; H# r! f5 X/ \. T node=gparent 4 H6 j, @% ]! ]( }# o else: 8 Y# n5 Q. O8 F/ p7 k2 u! r: z if parent.left==node: & ]0 ]$ I* w& z) P self.rb_rotate_right(parent) 1 D; N" C& B+ I3 c& L tmp=parent ) |) B0 n5 ?- M# j1 R, L3 ^' W8 _ parent=node' m+ P4 B" K* ?$ t
node=tmp( @0 c5 D3 c0 \8 q3 W
parent.color=BLACK 7 i4 T% B: }: z2 K8 c9 v gparent.color=RED ' u9 |7 a/ F: v3 d4 e. g2 z self.rb_rotate_left(gparent) " }" u$ a) {" \7 D8 @ 7 f6 Y" [, m- o" o1 A if uncle:/ f4 Y* B( ~% P3 M& Z! G
if uncle.left: ' p" I$ |- T3 X. ^; A& m node=uncle.left % T k* B) Z$ u8 b) F# W parent=node.parent# K" {( \* t8 A
7 {9 ]5 E: }) G
* K& y& i& T! o/ U2 h3 t$ V
self.root.color=BLACK( b2 p" v0 _% x& S' W1 ]) {
0 s) @0 j# y c$ [* s. L
! Z v) V9 Z( z
def rb_search_auxiliary(self,node):1 M8 Y( G1 |$ t7 ?# O* a
tmp=self.root1 d% E. ]. I( S6 D0 |
parent=None/ D3 p9 D+ I" m3 g5 U
while tmp is not None:8 O7 g- @4 Y- ?/ r
parent=tmp 0 y9 ?5 p) V" d2 R0 H cmp=self.cmp(node,tmp)4 H! g7 d, Q2 p, C
if cmp<0: 7 \5 T- b5 \) g/ f tmp=tmp.left+ U: [" b- c- a) r+ U
else: : l6 z. W2 H2 n# n% t5 D; H if cmp>0: + c0 X1 Z" d% B( ]; w0 d tmp=tmp.right7 \/ J" G9 Z+ h* @2 @, t* M6 D- q
else: % {/ z& c) l; ]: s9 X return tmp,parent2 m& j- z) j# Q# w/ M% `: T
$ r7 N e% v2 R5 J& g/ k
return None,parent$ S8 W# B8 w) s* Y6 Y4 X d
0 g$ m, x$ H# ^, {. v+ o/ h( X
def rb_insert(self,data):1 h" X5 O% \- [ R5 P) l! d5 m4 P% ~
tmp=None * r9 W+ |( e! X1 S: A( J node=Node(data) 1 D* ~! q, _: n7 C8 \' | tmp,parent=self.rb_search_auxiliary(node)7 Z1 ^+ v6 {; ?3 m
) O' @7 [! n; r, [* y
if tmp is not None:8 J! ?& Z# b$ v& J1 e# `+ A
return % |5 h8 b q; o& e y T" L7 y- ]3 O& w
5 u, X7 R! R1 T u
node.parent =parent. X! W2 {* y _- r& Q- |+ @: H
node.left=node.right=None1 S' g, v" H N! S
node.color=RED ) z1 `) t% W! S/ \8 w ! x% N- e+ X6 v q/ Z, [' I if parent is not None:! k6 _$ x& p; K/ u2 d( L
2 ^; p: }+ v S7 J: s if self.cmp(parent,node)>0: R/ H- ]2 T6 K+ G% Z) E8 e
parent.left=node , Y4 I0 a2 g- I, I4 s else:$ D+ S" {' v! q1 ]4 M
parent.right=node4 N( z; T, O5 z/ a
else: 4 R: n# G7 a/ T1 C self.root=node2 X* b: [- D, }- `8 i" B
return self.rb_insert_rebalance(node) 7 ~7 ~* ~6 Y4 i n8 Q1 J5 K/ O$ w0 [/ Y! D. x f
def rb_erase_rebalance(self,node,parent):. O6 @/ Q* H4 `( C5 H+ |& O
while((node is None or node.color==BLACK)and node !=self.root):9 m! S& y% k, A4 Z8 b: f O
if parent.left==node:& ^! N4 ?4 B" V% G7 c
other=parent.right. @- F5 [5 N' Q5 F
if other.color==RED:+ T( {& O ] R. x1 D! k
other.color=BALCK 9 @! E u8 ?3 ~5 k, e2 l' p parent.color=RED ; ~( j& S0 X5 L( y, }. e self.rb_rotate_left(parent) 7 N ~( F# b" e. b other=parent.right 3 D; Q8 Z t* |4 a if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color ==BLACK):' u4 L, p$ @0 ^2 ~" j& ~6 n
other.color=RED ) {' g4 t; s3 {0 s) R2 {+ I node=parent ( l, h: Q/ U. Z1 l6 t1 c+ U/ B parent=node.parent R. ?7 T4 m- ], V* ]# B
else: % J2 ~4 H$ e* } p& F8 H if other.right is None or other.right.color==BLACK: 7 @1 E/ X! K% j( A4 G" B: f/ h; Y$ P
if other.left is not None: . [7 a6 n9 Q7 Z8 T3 h other.left.color=BLACK 7 T% c" m& K3 ]& k+ t: w; K% W other.color=RED + \; a1 r, k" D) ?1 C7 Y/ D: x self.rb_rotate_right(other)( Q9 o0 l ~# D+ N2 ?
other=parent.right $ ^$ M- a: e" F. n; l- x. z- ] : @& p+ |& r9 x0 I other.color=parent.color1 L& C& H3 V, o" Y' W
parent.color=BLACK ; v2 b( L4 k) p; L% N3 e9 l if other.right is not None: 4 M% X9 N$ J9 X+ D8 m$ y( ] other.right.color=BLACK , {+ ~9 _( N4 I( m( F self.rb_rotate_left(parent) " K: h& [2 O( T9 H3 {3 } node=self.root & E: G; N3 Q, ^9 C break 0 x$ X3 P0 u3 A else: 4 d& g4 E3 v" F8 N6 s other=parent.left! Y$ y# w+ `5 B5 ]
if other.color==RED: 1 f: L% h7 F( r other.color=BLACK 0 C0 `$ \) {: y7 ~ i& t parent.color=RED( u* I& [8 O$ y3 C. t4 B1 l
self.rb_rotate_right(parent) ) k7 `2 ^; }2 S! w) J other=parent.left + W& Y8 U; u9 S% ~ if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color==BLACK):* C' j- z' t; t$ p1 O. U. r
other.color=RED ) A) U) Y, G5 d8 A# l4 n node=parent$ `; |2 t/ Z) e4 U' M
parent=node.parent u% i: r4 `- r- ^! G# C) f4 d+ U* X
else:3 E$ J. T0 h" N. e1 b# }+ W j! K
if other.left is None or other.left.color==BLACK: $ P: f7 k- h" t* m* q8 R if other.right is not None:# F S) l) ]0 a- _. A
other.right.color=BLACK' m' g/ R5 Q( p; ?* V
' u' r: T. q' Q: ~) O3 h% p3 R other.color=RED& O2 {" V" {( ~5 Z
self.rb_rotate_left(other)& c' \& n+ Q) n, |4 \5 M" Y
other=parent.left ; A- C; h* h% x: I* }# H* r' I1 `, Q 7 P. K3 x1 Y' `- _6 J# X1 K other.color=parent.color7 b& c1 `2 Q% F& u- k
parent.color=BLACK 5 F' d& \7 a3 k7 K) t1 B, m# b8 v4 r p% q
if other.left is not None: R- C7 {; r0 B" M9 b
other.left.color=BLACK 1 \7 Y% I/ @; A9 a) U3 R8 n4 l4 A+ a
self.rb_rotate_right(parent)8 z+ u( n, Q4 X
node=self.root . q( w0 @! F' d! r& d; q break" s: \) F' t* i7 U5 [8 J
0 K- v+ I! N- R$ L0 H9 @/ @* H6 [/ a1 X
; U! y9 ?1 T7 Q3 ?, h/ x if node is not None: / S& {' j! _# y! e _ node.color=BLACK ; ]# d. o) N# ]+ f " V7 G$ l- B3 S' B; e! g3 x' C def rb_erase(self,data): : y3 W% s6 I7 ~% v) x$ m% O% w/ y tmp_node=Node(data)5 D8 d" W5 Y5 {3 L# ]
node,parent = self.rb_search_auxiliary(tmp_node) $ x) N2 m1 @* S6 U: i if node is None:2 O4 D9 F( Z" E4 h4 ~
print "data is not exist." 8 X4 j6 q. Z' ~5 f# p return ! e1 b9 q# E# F* e! Z9 {7 W1 u0 ?3 R1 x 1 \& D8 c2 B6 n6 e) i0 K
old =node5 I% S) y! f# G {1 n
if node.left and node.right: ) D/ w% v" }! R) |7 t node=node.right0 ~4 c5 E/ O8 x1 c9 h
* b. F! b. w. O P" f: P2 ` left=node.left - P* i ^1 C+ u* t) e8 o5 M while left is not None: . q2 i& v# R( k9 i node =left( T5 p' Z3 B3 k& _* @
left=node.left 7 Y- X# o/ }$ _9 x R1 s5 n; N8 l" o5 P$ w, M+ p
child=node.right - g& w* `- E: ]: n" a) h parent=node.parent9 @; r% ?2 `. E" g- I. B2 E
color=node.color i3 ]: p& {# N8 \ {" ] s- { ( f9 V% p/ d' T( t( c if child: 6 t# W1 D& O$ C* W3 ]# E+ P$ @ X child.parent=parent9 T% L2 C* e& A/ R, S
if parent: 8 z; O8 g6 f/ `+ v; p5 I if parent.left==node: 6 |$ M* Q2 r- L L parent.left=child% G& f4 A# `* m$ d9 z" l8 P b
else: 6 ?2 _$ ]8 Z. K& A' G+ G parent.right=child. U$ F) H. W! S5 C3 X! Q