! I% C( X! _& S4 U' ` self.root=right/ T- @0 ^9 \4 S9 U
else: * l9 M6 \8 Q( e) n# J if node==node.parent.right: ] t* M3 T: n, J
node.parent.right=right9 W- u& W4 @ |1 {. D, v
else:& |* T/ O1 H% z4 a: X! R. j
node.parent.left=right ' \& f( |( b( K/ z node.parent =right + j9 q4 b+ u5 V$ ~ 9 M' L( @% ` ]! w ( i# ? K4 U/ N6 n4 w def rb_rotate_right(self,node):. D0 H) ^& s3 ?/ Z3 r$ P, Y
left=node.left ; t: h, {( `3 D u8 U3 \8 Y$ q node.left=left.right & `! U. |! d: Q8 U+ }) I$ G1 Z& b [+ N! @2 u. d
if node.left is not None: & O0 a$ j* R% ~3 c; t! \8 v1 @6 V' { left.right.parent=node. u1 @; ^" Y8 T8 b5 s: J, R& k
2 C) H& e# f" d) z; [) y5 s1 x left.right=node * v k Y& \/ j% f& O7 \# w4 z) ^$ I left.parent=node.parent8 g. T4 N* C6 x
* A9 }- B4 a* O9 X if left.parent is None: 3 v i- |; |+ l" C# h self.root=left: r! s/ K6 r2 S: r6 F( M4 ~
else:( p. y4 l& c* Y$ j; s% d
if node==node.parent.right: " M$ R/ O4 I# u- E+ h# \4 l. p node.parent.right=left4 J* C# w/ m" B7 |( O
else:6 U+ _ ~' e5 |+ D& v; A. t- ~
node.parent.left=left U* I$ l4 l6 m; D$ o8 t node.parent=left( A% B9 D P" |4 H/ ~
0 a0 G" R9 Q6 y: s1 _7 A v def rb_insert_rebalance(self,node):. f3 W$ f7 k; F( C7 w8 ]: Y; d8 s
parent=node.parent' g% k# U- v" T- D; x4 C$ p
while parent and parent.color==RED: # n: B$ \5 P& o% i gparent = parent.parent1 \6 \: x3 v, E$ M @9 T
if parent==gparent.left: " z0 z( ~' y: F3 v uncle=gparent.right3 S6 V4 ]5 S3 Z5 m j
if uncle and uncle.color==RED: 0 p+ `; T) f2 U$ c9 C1 X1 M uncle.color=BLACK ! C( I9 {0 I+ P1 I3 j) U6 C! O parent.color=BLACK7 I/ C/ ^& C* g4 P' ?0 U
gparent.color=RED; r$ e G4 f$ G7 H Q& e: r7 W: @
node=gparent9 t' v" o* j9 R" y$ @
else: ( T% W6 t- w8 C; M# E2 R if parent.right==node: ( P6 M' [5 l2 u0 \9 P self.rb_rotate_left(parent): \. m1 b% Z U* U$ X
tmp=parent 5 [. g% Q1 U7 O9 A& G parent=node # _% H6 x/ ~+ b3 e- D node=tmp+ c6 u5 r8 E% m7 C
parent.color=BLACK % N5 }7 _, ^1 d ?: D3 x$ } gparent.color=RED/ f, c/ ^1 _& j
0 S( p! C7 y3 e9 u& i8 _- s
self.rb_rotate_right(gparent) ' x6 ~8 H& J6 z2 }3 b( ^6 G2 F$ }1 X9 D, Y, U
if uncle: ' s' p k& G" }* T! t+ B if uncle.right: : ^6 `& ]5 e1 b' j* |9 g node=uncle.right/ S/ }1 N4 n2 q# C- a4 V& B: L& p
else: , I+ c$ h$ m+ d: n! C3 |6 a uncle=gparent.left h( ~$ w# I: V+ a" [, T if uncle and uncle.color==RED:1 h/ ~8 X4 Q5 s9 }* N" B" Y& W
uncle.color=BLACK 2 a- E$ Z# ~# G" g1 b j2 a parent.color=BLACK + |: ?# W: H, { gparent.color=RED ) _1 c9 v M+ d, p4 _% ^ node=gparent 0 I& F( u9 @9 C% ^5 o/ W1 N else:2 H5 ~. E& V$ d" n) k. \! U
if parent.left==node:- v; U: V$ U" J6 V' k0 K! W/ N
self.rb_rotate_right(parent)& ?& \% E7 ~! g( c `
tmp=parent) ?7 ?/ N' {/ V+ ~$ n
parent=node * A0 A7 M: V0 |# w) Z node=tmp : M/ C6 o6 `0 s X) u parent.color=BLACK - p9 X j# j! T { gparent.color=RED 3 z! m4 b' A$ ^# y0 M) b6 {3 m" _1 L self.rb_rotate_left(gparent)8 `; v$ F4 ?3 [' i3 }4 j4 g8 D( g A
: D: y3 h3 ]6 S if uncle: - g' L* r) P, R* W3 C- S/ `1 k6 P if uncle.left:3 E1 H" k, C4 L$ X
node=uncle.left5 E* w& d' @5 X
parent=node.parent1 i4 K2 f5 t0 L" h$ a7 }
# Z7 u" y* \' w8 C$ \/ n
9 b+ s& D! f: M; u% ? self.root.color=BLACK2 i' H! \9 X/ j9 |3 S# Y, e d
: f2 ]( r! |5 @; f 1 u! V6 R0 D9 h! z# J5 E* U def rb_search_auxiliary(self,node):3 H* @$ V2 b9 u6 M H i
tmp=self.root : _0 N2 H, _, n8 W9 b parent=None 5 O. ]& {/ m) P: |: x5 v while tmp is not None:. ^; b2 q" H* o. z6 j3 A" l
parent=tmp, T3 I1 u/ A! @ L% b6 c
cmp=self.cmp(node,tmp) . T% Z* M1 H- t* H2 L3 a9 L if cmp<0:2 _- K: G- @! g1 T& i0 V# _. l, g
tmp=tmp.left- F" P2 q) j; T8 }( P+ q
else:6 f o3 l) x1 W4 m5 s- A, [, l. u' Q
if cmp>0:- ]0 N5 |: B, g: ~8 B2 m, J
tmp=tmp.right) X% M) P1 p9 t8 z+ U
else:0 ]8 g, l# c' E8 r, r. f" x
return tmp,parent ( h; l: w! J$ ?6 s) N3 W" }1 B/ `" z0 T i s# x; B8 P0 f
return None,parent" Q0 m0 D# U! i7 A$ A: M* n k
+ H) O6 j8 @$ e$ y def rb_insert(self,data): r' l0 G" E: r, E
tmp=None8 K1 o) O, B7 ^6 p3 O7 t$ q
node=Node(data). q2 O$ ]" u3 t9 i; _
tmp,parent=self.rb_search_auxiliary(node)- Z- T [6 s9 X! n4 p
5 m: [4 Z3 w G, L$ `' u2 h if tmp is not None:+ n# o. r7 V4 y
return / d8 h# M/ a% [5 n) f5 E; M. g
6 y* W) {1 K+ b9 L. z
node.parent =parent' D. [2 E/ X7 d& J6 @1 ~& C: I8 M
node.left=node.right=None 2 }0 }7 q# c9 p node.color=RED 2 i F+ z# ~' U2 q/ T3 T5 T 0 k; ^, K' P4 s) n$ |. l. ~4 U if parent is not None: . @# @8 t; M! ^: B' h/ ~+ s5 q- C
if self.cmp(parent,node)>0:8 v9 U, ?) |3 W: ?+ f
parent.left=node* q0 P ]7 @. g* S+ P- |1 [
else:" S! C8 a% @& Z
parent.right=node, I; W6 t) M4 R: b2 T% d5 c" `
else: % a9 _/ B5 @9 S4 B" V self.root=node B1 V! u6 _- T, H: ]# j
return self.rb_insert_rebalance(node). v0 ~* p d" s' N, G1 ?6 ?& [
4 c# Y# p6 O6 d. C: K* I- e
def rb_erase_rebalance(self,node,parent):2 S; C+ l' n0 s. I+ i+ F
while((node is None or node.color==BLACK)and node !=self.root): , N0 x2 a o7 w$ J0 H if parent.left==node: # f* K& l4 p+ U1 c* G/ g5 X K other=parent.right6 u ~2 _+ c. v( m
if other.color==RED: : W+ Y6 H8 e% w+ k4 V! B% Z other.color=BALCK " I- }- T, z) j/ L# u6 A, H parent.color=RED * R; ~, x2 C# F) }7 c3 V" j" u% h self.rb_rotate_left(parent) * l1 D+ E( N! O6 \9 D( ?* m other=parent.right- `( t6 J6 u4 N* C0 _/ k
if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color ==BLACK): & u2 ?( y% [( z2 {: T5 i other.color=RED 2 ~/ R) Y7 H2 x% X+ P node=parent # z0 S4 T6 Q& r0 O parent=node.parent 7 ^ Y8 L9 X, E$ V) Q- ~ else: 9 h& I. B# ]& v" Z; [; p if other.right is None or other.right.color==BLACK: , @6 Q; N; ^6 n8 G( G* W1 w% }* ?
if other.left is not None: * J# q4 E( c1 |; S% y5 a$ E V other.left.color=BLACK / ?+ a- b. m6 @' V other.color=RED2 E+ _! m0 k! y+ s h! K& r
self.rb_rotate_right(other)4 P7 W; m% U4 Y4 Z
other=parent.right& }% t& J2 R }7 {7 R0 @& ?
" f% g' M( H, t# k$ z% Y other.color=parent.color $ P: q3 ]$ a3 b4 G3 Y& G6 z parent.color=BLACK . H J. b, G2 b5 f6 N" S if other.right is not None:/ r8 [6 Q5 W: o& Z0 F3 }. ~7 Z
other.right.color=BLACK6 u$ C8 u4 O# F) ?8 F1 }7 ^ }
self.rb_rotate_left(parent)8 s e f- Q, i
node=self.root8 N Q) R( g+ u# S, }& Q
break 3 a M6 E6 o5 R else: 3 W9 o4 y. \8 n5 h" S other=parent.left 7 D! ], R3 o# M% A if other.color==RED:$ T% s! \ I$ t9 N3 }6 k: f
other.color=BLACK C/ j, j% l5 U( D, _ parent.color=RED 1 ` n: S) y9 l self.rb_rotate_right(parent)7 y. g5 ~5 J! X+ I4 \0 U
other=parent.left; T9 ]& F5 ? @& B
if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color==BLACK):6 ~! p1 A, Y9 e5 `4 v
other.color=RED ! y k+ [" K' {! y+ g0 ^$ |9 V node=parent v2 Q0 U3 S; Y parent=node.parent$ y. Z0 d$ ]. R. R
else:& S/ [7 a, Z1 l* `( v6 _
if other.left is None or other.left.color==BLACK:4 _4 K( D; G1 V6 q8 |) e: S3 y
if other.right is not None:. w- y o/ ~' z Y7 s
other.right.color=BLACK; I$ I& t. S0 V$ v7 }
1 ?) I% C) { ?8 o& k" N other.color=RED, P8 C5 {. w6 ?- L1 @8 e
self.rb_rotate_left(other) 9 J |5 N; b, B' ~! H7 s# Q7 P8 `3 s other=parent.left # ]1 n8 ~' ]; p1 Y; m6 A3 Y ; R3 i7 Q4 F+ b5 c6 T8 B other.color=parent.color 6 ~( ?, t2 G* a' e0 H2 F parent.color=BLACK2 p2 P1 |' z! O5 w9 R1 u: V
* k& M* A2 ]1 G. ^! q P
if other.left is not None: ; P E: W# K1 ^/ G4 a" V other.left.color=BLACK8 w% u) z( `7 e
5 r9 n4 @# L" m- W. E$ k
self.rb_rotate_right(parent)2 [2 q6 W' T8 e3 V& g
node=self.root + T" [9 g8 p# h. B2 d break0 e7 l# o2 `) P" r2 J1 f/ R
) q% U' H6 }( q% ?. K7 X
5 [, W# Y& w% |+ b \6 {. k& \( _8 }, E9 b5 F
if node is not None:2 k5 g5 M$ B% G5 r
node.color=BLACK 6 J+ D9 W! Q( y, S( {2 L& V 4 F; {) U0 Y% ~5 \ def rb_erase(self,data):+ P+ F, f) `2 B8 T% {
tmp_node=Node(data) 0 A4 d0 C) h2 a; A node,parent = self.rb_search_auxiliary(tmp_node)7 A3 l% ?- `, v# P; v
if node is None: 3 p: g; B6 o8 B print "data is not exist." , F# {0 q, ~# p return ( j G$ l s1 j `, k # E& [- b, J8 D0 [; X' ]
old =node 6 `! U v% L; p- z/ z6 R# H5 o if node.left and node.right: & v" G5 K8 a/ m: |" A) m node=node.right9 ?" A8 r$ R$ N' m0 z q
& q' I# |5 B0 L; e) C) K8 d left=node.left/ u' g" Q% q. |& J( d% A
while left is not None:1 L: g9 \$ M% W
node =left . Z$ K ~$ I, y. Z left=node.left2 P+ ^6 g+ ^* B
' ?) V4 L3 \( E
child=node.right 9 k4 g" b n7 u" C" S' Q2 i0 D parent=node.parent5 S2 L4 B0 z2 `! i( e# {, G- I' E
color=node.color i5 f& g& E* s6 h: Y- C# p3 a4 ?; a7 i! D1 g# w: s2 D
if child:, H6 Z1 v7 O6 s; ?4 j, H. n- t$ Z
child.parent=parent7 Z {. a. q! n7 N$ r
if parent:, i$ W& q, |% d# E/ a8 r
if parent.left==node: ) D* X0 x5 p( B6 G) F; m0 }- c) I. M parent.left=child8 i/ X1 |; d. G% k
else:; y! J, Y% U8 W
parent.right=child$ o! ?. z% c! f, F
9 \7 c; R% A3 g$ I3 k else:& G+ S/ k0 s) N! K
self.root=child0 T* Y$ |! B! n$ N
- @' U& q- b7 x \9 G if node.parent==old:. `/ I( W( i1 T: c, `
parent=node! \& [$ D) M' \2 b! H
node.parent=old.parent 5 A9 A$ w9 g* F& [ node.color=old.color6 P O+ m: N% \
node.right=old.right$ \* A2 Z3 c, p
node.left=old.left : U, ~+ A$ E3 `% }3 } * d" f( w1 E- n- P if old.parent: . g- [) ^' ]) m if old.parent.left==old: " J, ]3 z9 k5 [ Q8 s; A) @; @ old.parent.left=node0 d3 l2 l% |4 J/ U
else:# P! F, p y+ [+ A8 ?
old.parent.right=node # a& @! v6 c3 ^ else:" m8 V9 I# I9 H( G, i: o
self.root=node, S" m1 Q0 S' x- }
4 r, R3 ]0 j6 B, \# U& x! _$ ^
old.left.parent=node # |8 p6 t! T" O2 D5 Q: B# d if old.right:; m# E' Z$ U T
old.right.parent=node + V; J0 n' u) a7 g. h& l! ~/ i8 G9 |: A, f4 W, X# ]
else:1 s4 \8 \7 J3 z% s2 m- Y
if node.left is None:, U& P! R7 p/ d+ ^" a
child =node.right / c, o2 l7 S9 E5 ~" j" k- Q else:1 Y7 \2 l5 w2 x
if node.left is not None: 0 d" J* B" c% s: Y. p# @( f child=node.left 3 Z: h. W% V$ m5 L8 c9 c: A( w! f9 d6 ?6 j else:: V! S, n" T% S8 b! W# q
child=None+ S4 B, }; f2 c' R7 \3 ?
parent=node.parent % U/ _2 E; e, v5 X% F8 } color=node.color( o! B4 S9 `! ?
if child: H9 c/ f y2 K9 `$ U) \' j8 P
child.parent=parent 9 R! u1 \$ ]+ I: g( R8 H* W6 Z, v if parent: 3 e, @$ C; O9 X4 ]/ w. Y if parent.left==node: 3 i2 {' K7 z: n2 Y' c parent.left=child; d: ~( U `. l5 G# N
else: , t: R' M* e- o* w/ X! R% D5 | parent.right=child( S( l7 D0 p9 L0 f
else: 5 v' c4 A: S* j, u6 W self.root=child 6 v7 q7 [; m- E3 ?2 R4 W. A ; P! Z7 V& X! f, N6 D Z( z! i% d if color==BLACK:# g; p- n A7 F7 b6 {1 J
0 E, W" o0 g/ j+ K self.rb_erase_rebalance(child,parent)' f. j/ D# o' A* _0 A* d
# B9 \5 m$ w s$ _: V+ p- S: n' }% o . f5 w+ ~6 m6 y# U( j1 U' L def rb_travelse(self,node):6 ~$ i- d" L9 L8 ]
if node is not None:: |7 I" W5 f% f8 U s
print str(node.data)+'\t'+str(node.color) ) O9 m. H9 g& r" O9 m* O( D& U self.rb_travelse(node.left)+ p1 h+ k5 L$ @! e! e
if node.parent:5 Q: n+ @9 |5 b. K2 U# P" H& ?2 v/ O7 R
if node.parent.color==0 and node.color==0:) R8 ^' P) p+ {
print "error"+ T* v& G: x( f a
return% l! H' G s+ w. H8 Z
self.rb_travelse(node.right)# b# L1 F* h$ Z. H! v# h9 v
if node.parent:. l# g* w" q. S1 @0 R+ E4 u3 a
if node.parent.color==0 and node.color==0: ( Z' m2 e6 \& R# ^% w9 J8 v( j2 ^1 o print "error" 5 P2 M! R- s7 ^5 x return8 a& p `7 D0 k: R2 E0 ]
- a" }+ F0 ^, l+ s+ p) O( x t
return+ x" f6 w7 g1 l0 g' j. u9 j
3 y6 t. j3 M/ {% t, S( D / ], f) K# j! j2 \
def cmp(self,node1,node2):# [$ ^+ } W* t' h; s% i
if node1.data>node2.data :9 P0 w+ G5 W/ n$ K* {9 L) u% g, s
return 1 ( C$ H* c( m8 {! x, W) H9 R if node1.data==node2.data :1 W, [0 X. ~% P$ \% P+ w/ p
return 0 , [/ t, ]. z5 o: N" S; ^5 G; j: L if node1.data<node2.data:7 C2 m* B' R* {2 q. b& ?
return -1 9 ^' N- u5 M8 v# l4 e/ n) k, F5 T3 Y$ n- `! A, f
if __name__=="__main__": " J" h: _: W5 g2 t print "main". a" {6 K- q/ C: G/ w' F4 G- r2 \
data=[28,6,39,78,6,43,61,56,71,38]. ]8 i3 ~* {* I) L9 m
#for i in range(10): & G, g, f5 g0 G2 ` # rand_num = random.randint(0, 100) 0 m E1 l, J/ k$ @; R # data.append(rand_num) $ F" p% S8 ]9 I1 b& J #print data * e) q. V% Z$ H% y' h ^ t=RBtree() ' E3 n: R1 N! [3 j1 V( o8 K1 f, N+ d) s4 \, o6 \
( d3 D9 t8 A# a
for i in range(10): % r# x$ C: f7 _) @7 F2 `1 j t.rb_insert(data[i]) / h( R6 @2 E0 E + r8 Q9 v/ D: o% E7 H% Z# R$ m6 N+ z. k r( @
t.rb_travelse(t.root) 3 V% y4 c& F( Z% q# N# z: L8 O - M" Z. j6 K d+ G print "---------------------------------"( U* u0 c1 s, k! {7 f$ {
t.rb_erase(data[7]): Z2 a" N! @- q2 `+ b* n& i1 t5 [" ^
7 ?+ b ^, k8 M
t.rb_travelse(t.root) 3 L' Q, O9 a1 ]1 B6 E- d, x) I5 B1 Q/ Q* S y" \