: y; j* W8 N: t! n7 e+ k def rb_rotate_left(self,node):; c5 s6 P/ Q2 X8 b$ m. k
right=node.right) w4 |) w4 n- S1 R4 G! Z2 C
3 { `7 @. i: P. v) l- F
node.right=right.left q* @; ~0 k$ {5 M3 J7 A
if node.right is not None: 6 M8 e6 \3 [4 r% k2 \! N right.left.parent=node ' z; \1 k4 r9 H, L2 B! W, _# Y ! y$ C8 \ h8 @; ?2 n! q right.left=node- m1 g+ v* w' X2 k
right.parent=node.parent 2 ?3 |# D: Z! [0 O, N3 y( u; D9 N/ g! ?1 Z$ q
if right.parent is None: * Y- `8 D% L/ ]+ ?* w- c8 w% t % Q! e+ o6 I+ N4 ^5 ` self.root=right " t6 D0 w; E- S6 G' T else:7 p* L' W! d; @) v6 Y
if node==node.parent.right: / O" H* h/ `6 r i, g5 y a# X node.parent.right=right # U4 O! v- M w9 @ else: 3 E* k# F5 w1 Z; F node.parent.left=right' l& {- T/ T4 A* b, {/ M
node.parent =right 5 n& G* A3 M* M+ B. I8 n6 r, \) {5 \
" y# ^& L, `. W' k7 M& G def rb_rotate_right(self,node): K9 ?9 _6 i* B! {, G
left=node.left 0 [8 G2 q& k: g% F node.left=left.right ; y7 ]: C3 @) t" S6 _, k: V! j! t* b+ v5 w1 y) m! y x
if node.left is not None:- `8 t4 _; P9 ], x: P
left.right.parent=node e8 B3 s `; }1 S
- l0 A' i2 u8 ^5 ]+ F" p( E
left.right=node : |# Q4 \6 [7 z/ A+ A6 Y8 U4 ^ left.parent=node.parent * R! c9 N% Y& d8 @ : T, t2 ^. N* k( s, ^/ W8 X5 ~ if left.parent is None: ! o% e# }7 Y: K# R! e y self.root=left* X8 R- c: X) w
else: - _0 w0 x0 I6 w# `$ z1 `! p# O. A if node==node.parent.right: ; r8 d, R" j9 E' e node.parent.right=left4 b& ?6 D/ u4 F. _
else: 1 l: ` a& N! d$ A O) C! | node.parent.left=left+ q+ ?% o t$ W' W% p& \2 [$ i
node.parent=left, ~' r/ J- S. C
6 s+ D5 w1 G7 x. n3 K def rb_insert_rebalance(self,node):1 S) C( l; E4 u
parent=node.parent8 w6 ]" r6 g+ A f" U
while parent and parent.color==RED:' g" A p" `. p* }( c6 y
gparent = parent.parent _9 P/ D" l e$ e8 [8 C' ^) H
if parent==gparent.left: + v7 B4 E; G, k V uncle=gparent.right 3 V: ]2 W! \ e0 d( u- g if uncle and uncle.color==RED: 2 R/ C) v! l# _) l& F& s: U% D uncle.color=BLACK( ]5 E* c6 o4 d8 A; C2 @
parent.color=BLACK + C1 E3 ]9 G' E2 | gparent.color=RED $ g$ X$ a) c* n8 I1 W: h @7 a node=gparent7 F; f; ?* _7 @% G
else: . Z% B/ g+ `+ J3 M M) c; t1 X if parent.right==node: + |0 y# I1 k) v0 V2 q self.rb_rotate_left(parent)" Y* P7 ?+ E7 ^* ^+ o3 j" L
tmp=parent 5 E1 o( W/ \% C parent=node+ O8 v3 V# G( k: A! h
node=tmp 4 H& ` F) J0 U$ o) u parent.color=BLACK , r3 p% `& E) K$ a* J* K" u" C gparent.color=RED* ?: m/ K% }( n4 T8 l( z
1 N. j. G5 {. o \" f4 e self.rb_rotate_right(gparent)" d0 u0 b6 H0 R# b
" B9 s+ A* |2 g+ e# j' U
if uncle: # {+ s D8 W! R4 y" l; i if uncle.right:' P& k9 x9 u, u# j- ]; Z+ t0 k& W+ W
node=uncle.right" R8 ~3 Q+ R0 ~, ]/ r- \8 Y
else:* ^* O' [- L0 @! Y6 Y S/ Q
uncle=gparent.left 5 ^" N1 K9 y; |4 k) X2 M; Y, z5 l if uncle and uncle.color==RED: 0 j5 b0 P4 V0 S; F+ {+ x uncle.color=BLACK % u. G2 d& r% ]" k parent.color=BLACK2 f* J5 D) I7 S9 m
gparent.color=RED H" d* l7 k" j6 q# f) X2 @" a4 Y node=gparent9 [+ r5 L2 W# N1 Z# j
else:- F! e3 f. y; {0 l& @
if parent.left==node: ; {7 \& A D4 l. S# j self.rb_rotate_right(parent)- N: @0 W% v8 p- o
tmp=parent ) O* c+ [" q$ v/ R; e parent=node& L; s- C( e, y; V
node=tmp4 }* Z0 F5 j. o: g# w1 }6 f' v
parent.color=BLACK7 y- W! y/ @ [0 p% v* U
gparent.color=RED7 S/ Z% y6 M0 l0 _9 }0 p4 s- @
self.rb_rotate_left(gparent) 3 l" n- e8 K2 O1 _6 q8 H6 S$ q8 Y, \% z9 C, h$ M. N
if uncle: + S; L! S; W" x5 A6 `, z! x if uncle.left:4 s+ X7 `9 T* K& o/ d8 M v
node=uncle.left $ w8 p" S2 N- `) e parent=node.parent ( @1 z6 t) v, X7 Z- e ! u, u0 {3 j0 X2 M ! N, H. j v) a& A3 r self.root.color=BLACK+ i& R6 `6 M; G" V! O5 k
+ H! ]1 G g2 i$ G7 D # u9 X, B- I7 p5 I def rb_search_auxiliary(self,node):- |; m8 j4 o4 w, a c2 U
tmp=self.root) G3 q: k1 G. e' Q3 E0 a
parent=None / Q3 _5 c1 ]& T" L while tmp is not None:8 c' [4 z! u- _1 S$ ]) C
parent=tmp " l" r, {8 [, Q) r. j8 a5 g+ @/ J cmp=self.cmp(node,tmp) . N6 ?* {8 z8 Y, X8 ?/ S1 z if cmp<0: 9 j7 u j* e. ]/ s* Q tmp=tmp.left2 p; b: e7 q5 a- [) `/ k8 ]
else:, x Q) t4 ^ C8 [4 i% a4 u
if cmp>0: & H! U* O5 h- |. B7 r( U tmp=tmp.right . p9 T, f% Q V( s9 q else:+ ^) G4 V+ w% x/ y+ z
return tmp,parent 5 u+ E, q' y3 N5 Y4 @- w# ]$ @ 6 r% c- M7 M6 E2 p' q return None,parent- O' q% z# z: y, b Q
7 Y7 Y# S) Z- V6 L' c' {, v def rb_insert(self,data): - _+ Y1 x2 D2 S: o; L v tmp=None 3 M1 L% |& z% w+ {* o node=Node(data)8 y5 o) D, o! y
tmp,parent=self.rb_search_auxiliary(node) / X/ V! g/ V; [ z' `% G! Y; i 2 h2 r& u+ J' X3 l) m if tmp is not None: - E- S2 @/ w8 Q: |& R0 K- b% D& a! j return / O6 W R E$ k9 Y6 l4 m 1 c8 p3 j! E! q2 G% x node.parent =parent % }. V6 R& Z5 M$ h/ w4 C1 c node.left=node.right=None 4 \5 L9 P) H4 b6 O node.color=RED& K1 E. E; ^: o j! J
% ] i6 a4 A. v x2 Y0 a, w5 w if parent is not None:- |+ p& J: t9 @" x9 B
" p3 S! f# `( D* }$ N if self.cmp(parent,node)>0:: m$ j& K9 m/ V' E5 A# V1 ?) b
parent.left=node 6 g3 ]3 M! u* d0 m: y else: 8 m' S. Z3 K7 u* u& ` parent.right=node " L( Y/ X; l7 d: _# G# ^ else:1 y0 _4 d* O" G+ ^
self.root=node. j2 c+ u! E1 r& ^* ~' C1 B; `
return self.rb_insert_rebalance(node) 3 L# |. I7 m2 { T6 ` 8 N# d1 H" M n6 t5 g9 p def rb_erase_rebalance(self,node,parent):5 ~, Y3 M4 m! ?; ~3 ` \
while((node is None or node.color==BLACK)and node !=self.root):: u1 ^, F: R: ` ^2 ]0 V
if parent.left==node: ; C# b1 l8 }. W# | other=parent.right0 g; D0 P) d2 Y u# {
if other.color==RED:6 G& Z( o _ t& I4 Q9 X" u
other.color=BALCK" _6 b. H1 t( M3 q% S8 Q
parent.color=RED0 k6 A' K$ p7 v) H4 v$ [8 Z" I
self.rb_rotate_left(parent)5 f3 I$ ^+ x: L- \3 Z
other=parent.right! g' x7 h; d. O6 }( b8 j4 A! w6 y
if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color ==BLACK): $ O# Z8 Z% i6 k9 N: e other.color=RED+ ?( z, {0 j+ {0 e8 q/ y) V0 v% A
node=parent + T6 s) v( h/ Z/ N& u parent=node.parent 4 Z: z: s2 L. {2 y' L else: * H' h, n& v5 ^( r( f( X if other.right is None or other.right.color==BLACK:% O* W+ r# j- ]2 v
/ t, Z8 c+ a6 P8 A: ?
if other.left is not None: % }( @6 w# `4 J$ b4 X4 w other.left.color=BLACK , z* B3 @- |: ^8 n! Z# W( a2 G$ ~ other.color=RED5 b6 ?3 T2 I' S+ L9 H- S
self.rb_rotate_right(other)% |0 I% l, \7 x' M, E1 J
other=parent.right * n* \% `# q& W- g1 u8 t0 `, f. c O' ~
other.color=parent.color ; q" h. T$ N! e( e+ I$ X% d- B parent.color=BLACK $ U6 b- r& h$ t. l6 n& B if other.right is not None: ( d0 K! k5 v" Q$ r other.right.color=BLACK 7 g7 h! J! ]1 t4 T4 o8 V self.rb_rotate_left(parent)1 f& N$ g5 x# O! B( N) E
node=self.root & q( o! c3 m, {0 Z$ e# {1 A: g break 6 D3 \+ l. K" ~9 y else:* d+ d( K( P* b3 q
other=parent.left 7 z# w V3 Z5 ~$ a6 R if other.color==RED:6 `- G( S& o5 W& k
other.color=BLACK, J6 N1 y8 n3 A& ] V% N p) k0 [% U# D
parent.color=RED3 F3 |' E4 A+ s/ |4 _$ l, k
self.rb_rotate_right(parent)9 D1 F* q6 p F
other=parent.left 3 P0 P3 B8 e: W, _ if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color==BLACK): : v: C5 u) U( D8 q. c other.color=RED . u6 `4 R7 E% K+ {# u5 I$ y node=parent/ e6 @! |. L) V8 s! e% `
parent=node.parent, I* V2 s2 ^' @" R
else: + h/ Z. h$ L0 Q) M+ _, H% e if other.left is None or other.left.color==BLACK:8 N; _3 m# |3 _2 e
if other.right is not None:6 t5 O1 v7 U* L- j
other.right.color=BLACK q& [8 | h2 J6 Y1 P5 n
! u* P4 J9 U% `, f; O other.color=RED: I( T0 z" T6 a! q9 i
self.rb_rotate_left(other), e8 T) Y- |8 x% X) X! R
other=parent.left 1 d F9 o$ _3 l9 B) w5 ]! y, F6 C- x: |$ B/ ~8 G+ d
other.color=parent.color- s% O5 W1 X# `, M- F$ y7 m
parent.color=BLACK 3 c, S$ W" \6 ^) N2 w4 Q& H' Z5 }4 m( m! {7 ]
if other.left is not None:0 U# d1 U. j& N5 W
other.left.color=BLACK0 n! H% U" \/ {& v0 J$ j
% g4 }5 w5 a# x1 I# B! q. k
self.rb_rotate_right(parent)( Y5 x% {) |3 g$ t
node=self.root7 H! U8 i* t3 J7 d
break 4 h. A5 T2 b t" t1 W+ S 3 T8 Y7 e' A4 p4 M. w% G " k* l* {0 ~; F @) y 8 M/ Y `! k) c7 ~ if node is not None:) }7 J/ L. E+ I) I# j/ z; K y
node.color=BLACK + ^* r# K: ~7 p6 U k! u! ^, w$ `0 q F/ O# w' S
def rb_erase(self,data): 4 p B3 @% `2 i3 u- _ tmp_node=Node(data) % u: A5 g6 v/ E* I$ f7 q4 |* E node,parent = self.rb_search_auxiliary(tmp_node)* ^! X' [% j3 h
if node is None: ^* x% G- D* b" U; H( |. N$ `7 N print "data is not exist."1 V) `$ U, E# ^. x) E6 J
return ! A- P+ W# r& T! q " S6 N% d8 F0 Y; Y" Y+ W old =node $ @2 V% v/ t: v, d1 Q if node.left and node.right: - N) X+ b5 T5 L" S& M6 q, t1 h node=node.right ' |& s5 J8 v+ r" u9 k # O! v+ a2 T+ r# {+ E2 a left=node.left - j6 I! e7 y+ @& }& @1 w while left is not None: 9 O* Q2 f# z( G/ F/ t$ R9 {1 F3 b; x node =left4 `" x( W( j; g( u0 M6 a
left=node.left( R: w" Q4 Z* V; {$ u
$ s3 h- Q! K5 x child=node.right , `% R. Z$ ]$ d e! S( ^$ o; s parent=node.parent 5 R/ i- |! k; i5 X8 S color=node.color1 }! l3 n: k7 Z( [' [: [7 ?+ O3 Y; K
0 J( v( n* A! `) C& p2 c9 P if child: b }1 [% n# W. C
child.parent=parent# \' p' L9 C# M1 |' `. V7 q
if parent:( D9 M% Z- ?1 N0 L
if parent.left==node: 7 J* X# B9 d1 V# e0 {7 r3 R8 B parent.left=child # b9 P) G& o$ s# {' u& ]- g: K else: : y, t& t3 w5 w" A& w7 N parent.right=child 3 p2 |5 y( W/ J- o$ R ' `1 h1 E) h, f$ \ else: 2 _, M5 U" Z! K% P0 \$ @; z9 W( R" L self.root=child / t |0 c( _0 X6 N3 f J; @" S 9 @7 L0 x! d6 s3 L if node.parent==old: 0 Q& J6 J- Z% ^ p parent=node! |4 p( X8 p& k C
node.parent=old.parent4 k; w2 s. d9 ~3 ?- u6 |) \* i
node.color=old.color6 A S( `# b. B- T- L5 d: x, X* E
node.right=old.right $ N6 _) E; F( Q7 k+ z node.left=old.left & r. o+ B S, O; J. n Y ~1 u, X, J5 i if old.parent:+ N# V+ p9 {7 A. I
if old.parent.left==old:) Z8 O2 _: H8 \8 ~- H
old.parent.left=node - R6 i) o# N% d. A: c5 } else: / \4 o* S: v% n# Z old.parent.right=node 5 s7 q. X# q j, {% e3 T+ {2 C5 I else:; t4 P' ]* R+ r: F7 ]
self.root=node 0 U% I; J( O+ }3 K! K7 T# R' _, c2 G2 o% M
old.left.parent=node ; S* k, i3 C' g, T if old.right: ' P( q! c4 Y' \4 M; Z" e$ ^ old.right.parent=node& m+ `% e2 u1 q
& X; b9 i! E) b6 H5 a6 h. n Q4 e else:( F r) k% ?3 Z8 ~4 |, ?3 ]; A
if node.left is None:1 w. @3 G+ \4 b1 y& Y
child =node.right % ^4 D& Y* R; W/ r5 [' p else: s* X! e @1 H1 o, j if node.left is not None: , l$ W2 w S r6 `6 z( ^/ I8 _ child=node.left L L9 P4 L% Q7 B
else:* Y+ T, q' k. u0 @3 Z
child=None1 U/ [8 U. M1 ]9 j8 x) n& l/ Z
parent=node.parent6 l4 }- ?' B5 [/ L! e+ {+ \( X7 g
color=node.color3 q, H! D/ D, A+ }# G i2 h1 f" l( j
if child: $ V3 n* T, A- A- F$ f child.parent=parent - ^% f# \1 u I% F& [, J. K if parent: # N% \. j) x0 W$ v9 T( } if parent.left==node: 7 O! x2 N% S; i' o parent.left=child s3 ^( n3 P/ g6 a/ c
else: : W. ^5 d3 U5 U: D3 Y! T1 A parent.right=child( f- _" `4 u( h" k; y+ M: h
else:8 C) |* d e' Z! o0 [. N# R
self.root=child2 d- \. _! o! a2 @
z) U1 d; k4 S: x( ? if color==BLACK:. w# z$ L2 j! g/ y q; v; b# @$ i
* K/ b/ z8 E( k- p9 A% H5 s self.rb_erase_rebalance(child,parent) 6 Y& b( N* H9 s; C - V' H5 H: g: [. M6 h. |. ^% _4 [; e# X8 r; b8 M. j i" ?- f
def rb_travelse(self,node): 2 X2 J' ]1 g; \5 _9 u k if node is not None: 4 D( _$ |& m5 G' b9 Z print str(node.data)+'\t'+str(node.color) 4 h/ z% |; F y* o& [% u% h( Y( @ self.rb_travelse(node.left): U2 _' _! o* Q, W6 G
if node.parent: # P V, w+ i8 W4 w; z# t" | if node.parent.color==0 and node.color==0: $ j# J8 a2 @% m0 N. r4 k print "error" : ^" h5 B/ I; A7 h return" A9 R- M0 [1 T" V: e* D* A
self.rb_travelse(node.right)+ i0 g6 ?: [* d4 X
if node.parent: , {& w$ A$ O3 N if node.parent.color==0 and node.color==0: 7 q0 L* c5 `! y7 t5 X s print "error" T) g- U/ X. R1 `+ ?
return / |) b& E _# I T 0 [! {- R0 R& q' D* g) w return * a; n: O* t* [7 G- i' ~ , f3 F; N$ O* q7 t8 n % M0 {; w2 ~: R8 N def cmp(self,node1,node2): / ^- Z5 m& j* r% D1 n6 q4 T if node1.data>node2.data :7 s8 U7 ]- D2 C- U: m1 B/ y
return 1 . X. {" u% x8 M2 e0 e! O) p( \$ @ if node1.data==node2.data :( t, p) m5 D1 {$ \
return 0 , L. I- c! g( v! v/ q4 r: s; J if node1.data<node2.data: 6 F( \8 |( l$ Q i5 j# U" \! | return -1: n8 t4 \0 ~* s& E( ~1 I' U y
. |% e4 X2 l, x$ F w9 U
if __name__=="__main__": 5 ?5 Z% B) }6 ]+ { print "main"/ t- T) \& m9 O( w- ^
data=[28,6,39,78,6,43,61,56,71,38] 9 E* f/ m3 a; l7 g0 D$ Z #for i in range(10):9 C2 x% }# [1 R. }% K
# rand_num = random.randint(0, 100) 4 a8 x" E; }8 R7 I8 H. A # data.append(rand_num) 4 y. x) \: a4 B ?1 O$ M' u #print data; `$ m* s7 k9 K3 C0 b
t=RBtree() ; S& x4 x! X) k8 E# l% i3 t0 }9 m) w( C) w
& p6 W3 }$ k' V8 S for i in range(10):6 C. _' o" K+ K% f
t.rb_insert(data[i]) 8 o I! V% ]6 o+ X% z! h 5 ^# Q% B ~3 G + }6 b$ \ ~# e* ^% I7 l t.rb_travelse(t.root)/ t0 I8 e( A, T8 \
4 z* ^; U- f% e
print "---------------------------------": Y" D6 ~7 G! R& p& I
t.rb_erase(data[7]) ; W% |) I) R2 Z% s' e) d5 n* } . a$ V, D' g: w! B* B n$ ~8 u
t.rb_travelse(t.root): O/ \8 I2 B% R' B& m5 p- Q! N