; W/ C, o& V) V3 l! g if left.parent is None: * d2 P5 t- E2 q8 @# i self.root=left ( X% s2 l; x6 W5 M else: ) ?" h5 j) c& S5 y& e" i& @& c0 [# M if node==node.parent.right:9 O4 X# n( F5 J( q: o
node.parent.right=left' g* b: Q2 M7 ^! @/ l0 l
else:$ p* g7 o) l: A
node.parent.left=left9 G1 ?& Y. C" ?/ J0 p% b' F
node.parent=left + i$ I( r- M5 E0 r& R. G7 c* @ Y5 f$ b( _- L, H+ n
def rb_insert_rebalance(self,node): ' e/ Q( q3 e' V: Q parent=node.parent % w7 r# b+ M8 e3 l; I G while parent and parent.color==RED:. U4 ^7 }2 O" u! `# g; |7 N9 f
gparent = parent.parent6 Y2 A8 f3 y, H4 }
if parent==gparent.left: / ]7 S5 q( I+ D/ _) G. F3 [. p/ ? uncle=gparent.right1 z9 h- a2 H* s/ A: p5 K0 S
if uncle and uncle.color==RED:' E$ G# q7 ?2 P% B# l$ X0 r; C$ I- j1 h: S
uncle.color=BLACK$ [) d& B4 q* Z0 V- b. u3 d) }
parent.color=BLACK , l0 l; Y. E# ~# ~ i5 ?) y gparent.color=RED7 M7 a: {( f8 w! }/ d6 O
node=gparent# ^8 F3 D" j/ ^/ ~9 D
else:) C5 q) b* Y' ~2 i& W+ @
if parent.right==node:( a. c2 F% z( T, x; h5 T
self.rb_rotate_left(parent)5 f6 o0 x/ @0 x& U2 a7 h
tmp=parent # T6 W1 B8 P- H# G c0 S parent=node 3 S$ [: u: J7 y node=tmp ) Q& ^$ _% ]$ s- H parent.color=BLACK& {; i; I. r$ L
gparent.color=RED 3 j- r- j2 s9 y8 {6 f" B" e' A7 _# `3 s: e1 K ~. q# p
self.rb_rotate_right(gparent) # Y1 T+ }. K9 ?2 s& G" U: h& x8 z
if uncle: " S) ~ Q$ R6 p$ j7 L G3 t, l( B if uncle.right: % y1 }8 w2 J, O: r node=uncle.right 8 U( N l: ~; Z D4 R else: . Y; ?9 G2 Y) T. Z8 p4 H: U, s uncle=gparent.left 0 T6 i' O+ _4 k d if uncle and uncle.color==RED: 9 ~2 n3 x1 F* Q. \. j C! k uncle.color=BLACK9 X, r4 m, V/ j" `
parent.color=BLACK 9 d) E8 O8 h( x. w2 c gparent.color=RED ; C8 o* `0 r7 { node=gparent 8 U9 o% ]% p3 r, g8 u* v else:$ [& E+ d5 N% }8 f7 }( |- N. A" ?
if parent.left==node: / W7 s5 [& H$ E5 `5 ^6 ?0 q% K% a" y self.rb_rotate_right(parent)" M5 s4 o& E9 r) X) ]
tmp=parent/ H E' V( u, t/ o$ e
parent=node ; o6 j0 d( x( d' A1 _! k/ m0 R node=tmp 9 o2 A8 K0 B+ {2 G& J2 S9 D" L" x' g parent.color=BLACK 5 J+ T- i% S, j gparent.color=RED 7 Y4 b; B* q d, t* C- @4 q self.rb_rotate_left(gparent)2 ~& M5 W- D( T- ]8 ~$ v
% N0 c. F$ U* j, x
if uncle:8 E$ [& C/ ~! `
if uncle.left:2 ^* ~" {$ `; d9 g5 z# o$ N# O. L
node=uncle.left ) L, ~; T/ _' Y2 t0 J parent=node.parent! x! Z0 q9 D8 `: R1 ^
; [) q9 B8 q" W7 s
1 @$ i, @/ H' J: W9 ~ self.root.color=BLACK 7 i' l* T& M) \% w. \% x8 K 3 z7 c- V: x3 P7 @( z( K) s 4 m% j& U3 U" J$ V( g# C4 A! h
def rb_search_auxiliary(self,node):1 O9 ^- A3 H/ l2 D" ?; o
tmp=self.root5 a, }/ w p9 F$ D% M* ]
parent=None; b3 i8 G. ]. ~+ e
while tmp is not None: - b5 X6 b7 a4 t* X n parent=tmp) \9 \3 h9 S- U9 S) _/ z: O
cmp=self.cmp(node,tmp)" s6 f+ R% z, P$ h( M
if cmp<0: 1 }- o1 o. C( T, z9 U tmp=tmp.left 0 L% B" Z$ C5 s+ u! e else:2 ?0 z0 [ ?7 R) H" I6 } X! L$ T
if cmp>0: 1 b: _+ a+ j8 |1 Y! v. p) O tmp=tmp.right / w$ g& z2 U) U/ q5 P8 u$ [" { else: , @* s! Y% W8 ~5 t return tmp,parent 5 o: T+ \7 ~. Y8 _ + w f& c$ e5 M' c: L* ] L return None,parent* [0 _9 S) \, H" t; G2 ]# p
u1 r4 A3 u- ^0 n3 a def rb_insert(self,data): 1 Q, t+ E5 |3 W- I tmp=None F T* I( s( M% g K t
node=Node(data) g9 S2 ]- c+ L7 r" o tmp,parent=self.rb_search_auxiliary(node) : n' l0 {5 G4 q8 F6 i6 D" j* n ) A2 q& u* M$ Z4 u7 v* r if tmp is not None: N% s+ X8 `& c( N
return 6 G8 |* ~3 |; r
8 g! a. J, J/ V4 \8 W
node.parent =parent . D2 m1 y: F4 p* \ V node.left=node.right=None 1 m% T. Z! h4 U. K! r node.color=RED 9 A( w& }* q/ {2 z1 u- [ 3 L; Q( p8 v) \ if parent is not None:1 o4 H" U6 M2 @4 P5 I6 K7 J
" z& t7 v3 [5 ?# O# I( p- l" k
if self.cmp(parent,node)>0: % d: ^" {" U; {5 V: W parent.left=node8 o* X0 d: ^! b" t" }- c0 E
else:1 \2 L x N6 A4 j. P" Y2 L1 w
parent.right=node; F5 Y' A7 b. w5 x9 w
else: ( Q9 M& f0 b3 u self.root=node " s D; @, I% Y5 W+ S return self.rb_insert_rebalance(node) 8 N' F* H" }+ K; Y" u3 H: C3 j# Q+ d; @7 s; ~& T" X
def rb_erase_rebalance(self,node,parent): 7 Y4 k0 p* E5 f2 n* J. A2 M/ w while((node is None or node.color==BLACK)and node !=self.root): 3 s, V6 a4 u6 n8 X4 | if parent.left==node: 1 U- Y* ^. d" N7 ?2 L other=parent.right 3 T: d4 m0 ? Z! `8 D+ X4 Y if other.color==RED: 2 w3 D z8 f) T( e+ | other.color=BALCK2 O! K- m4 b0 H6 s9 W4 Q
parent.color=RED* Z4 Y0 u- h- r1 ? x6 r5 \3 j
self.rb_rotate_left(parent)+ T; N4 _* l7 i: P5 U0 Y
other=parent.right % H/ C/ O1 S/ p: c if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color ==BLACK): ! F0 e D+ m! _5 [# n other.color=RED ( A# P( m+ T/ D$ w& S node=parent * h3 i4 Y, y$ q/ p parent=node.parent , Z0 i( E% A! i- X, @6 p- n. y else:5 O7 d' ?7 @) ~! J
if other.right is None or other.right.color==BLACK:$ G9 A$ K: S2 q& A
C9 H7 g7 A6 Z' E) q/ u
if other.left is not None:! x w# P5 [8 A$ p- I# M* Y
other.left.color=BLACK 0 W) }2 C! j% e other.color=RED; V; q4 |1 y; _0 D u
self.rb_rotate_right(other)& E% Q5 N7 z r& n
other=parent.right( Z5 X4 ~' a% B% q
/ g& j3 K9 _ O3 X+ G other.color=parent.color " g# u7 ~6 M0 l+ N7 E$ t$ }, U. b parent.color=BLACK # a/ J. n4 J, N C if other.right is not None:/ D0 n; L) j. z/ [! h1 G
other.right.color=BLACK* N- t* L$ {; [) B3 q- J
self.rb_rotate_left(parent) & |, A* @6 i8 O2 Q3 i; o node=self.root7 v3 P) k9 {8 V" g( X
break ) ]- E% G8 T$ E( p3 Z% W2 G else:4 {1 [. V5 B( A, f: ^7 V3 ^) R
other=parent.left , ~# J) p3 P( n) }: _ if other.color==RED:( F1 Y) X- a, I+ |
other.color=BLACK 4 J. B& p6 ~) o* H- z9 A1 u7 \ parent.color=RED% v+ @# q" d4 f& T
self.rb_rotate_right(parent)1 J/ a# w, e+ {3 }) p' ?
other=parent.left * y; G0 F" {; Z' q: ?) T: [1 [) J if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color==BLACK): $ o" P& Z6 Q, o/ W( ~( ^( _8 c; a other.color=RED, }9 D9 K" N$ K+ n/ a* r
node=parent 5 a, X9 l% u! R9 R+ V parent=node.parent. s" D+ m- l9 \3 o+ m8 d
else: + f* z: C8 Q9 R" U" t! r if other.left is None or other.left.color==BLACK: 6 [; N8 W, _0 U! g8 y' ? if other.right is not None:/ }7 `) X* V/ D- k1 e( o& @8 d
other.right.color=BLACK % c1 E v% }; N L: t$ G: D, F: T0 T5 b9 @7 s+ e" v' B* ?
other.color=RED E3 e: M# j" X7 y, F self.rb_rotate_left(other) \3 x: K' v: D, L5 e' f5 _ other=parent.left/ B# a+ [# V0 ?3 X9 m
9 N- \ @8 c% l( a" q a, A other.color=parent.color' h0 J' `$ W7 b
parent.color=BLACK 0 Y5 r2 [* i/ ^: d3 W& _/ b2 t) }0 S6 I) j
if other.left is not None: 4 s& @0 f# r9 N& y( K# z _3 H other.left.color=BLACK6 ~" k+ r& b o Q( H/ E) @" G
! k3 u3 F' K ^ self.rb_rotate_right(parent) " }+ o1 o- w' y8 k+ P node=self.root ! l; p) c. o8 H' J: G& Q, L break & E0 g5 I q! D9 m! C/ O 9 V1 [+ [- X9 R3 u4 c' d/ m; r% B* C7 e0 o+ O$ d! J/ a) t+ q, J
4 Z8 i/ V. {4 N+ R
if node is not None: X) z" J; E. C! `+ Z3 `4 G
node.color=BLACK * B1 U/ Z6 J1 i4 ~/ A& Y, Z x0 v+ W+ C: s
def rb_erase(self,data):) H6 f6 _! k& @9 @. `" N
tmp_node=Node(data)( B |7 J+ N: Y! l8 c! ^8 g
node,parent = self.rb_search_auxiliary(tmp_node)8 G$ w5 @7 G7 S
if node is None:9 ]# ]) ?7 Z* R. m1 C0 y5 I" y' P
print "data is not exist." T# _' U% a# B
return ' J4 S3 p" E4 u: L. @9 u$ w ; r( O5 B1 i9 e/ R
old =node# V- ?2 R% X5 J6 z
if node.left and node.right: $ W* x4 v2 X( S; }+ D- L9 v node=node.right 4 ]" H/ i8 D7 M( ~# D! _/ g4 Z/ W0 x8 h
left=node.left/ y) W, }: C5 _) B3 ^
while left is not None: ; ~' z& z( B+ z0 c L1 p2 m node =left . k0 i) V- o2 }. f3 H2 Z5 D; f4 v left=node.left2 `/ r7 ~3 x. A0 y( i3 t+ G
F! N! ]& B$ O" } ?
child=node.right : ~4 f! b( X' c m, @ parent=node.parent2 {5 |0 ~" Y9 N
color=node.color - {/ C5 s" H$ X! y E * \9 R' I4 C" v% Y5 v v0 ^ q if child:* ]) l; j/ D& d& u' z2 O8 u
child.parent=parent5 A- O& ^7 I3 H, L$ {
if parent: G! z5 M1 L) v- N7 ~
if parent.left==node: 0 s( [6 _1 `" _3 k. H& _ parent.left=child ( r0 Y0 t3 S+ N, f# \* Y9 a8 R else:& n0 c6 P# j5 J. X: \
parent.right=child; K, F" Q0 \' _ K. Q
+ s' ^4 i `2 I0 L# u else:% m% P! W/ m9 g/ O1 f4 v
self.root=child. S- L s' D, ]9 W6 z8 k+ y# n7 x5 _
* \* u! N; ~: i q7 q
if node.parent==old:" l( C& {, P9 j& S. _5 P
parent=node * e3 P+ Z) _% Q8 Q; z8 o; E# P+ @ node.parent=old.parent / f- s6 a' @' [5 Q i! V node.color=old.color # B3 }& b4 k9 ^- T7 J node.right=old.right8 z5 o8 }7 r; y
node.left=old.left7 m, e, @# i- R$ N
! A; s2 q, T! I6 O: E# { if old.parent: ; s& ^' L# g3 O0 G# k* U/ O& V; | if old.parent.left==old:+ E( _+ g* `* t, o- w) y
old.parent.left=node # P) |, t/ J' T6 A else:' l) v# O n7 I7 \ K
old.parent.right=node 2 O; t) B& d$ L( U5 c1 K( k9 l else: - o0 E0 r/ J% V* M7 v( G+ L self.root=node 8 Q$ j" v+ z' Y \/ p K% e' u( u* C& T/ h- E6 w old.left.parent=node 0 S. u; ?6 W$ r/ P# ? if old.right:9 D4 U3 H; ~' h. G% z8 ?6 Y2 U. O' w
old.right.parent=node" R7 L H8 [; B. P
$ O0 Q! S- Y& b @' k+ } else:% F/ @. g: g6 e
if node.left is None:3 p6 m6 d; ~/ J% U( t
child =node.right8 v9 N/ P6 m3 _& j P
else:% y# ^, \- n g( C9 [& a
if node.left is not None: / H& d. |' H$ E- Q# z6 u9 O& D7 s child=node.left+ i2 |$ _ W8 ^+ N
else: ( ^% |! x4 O! e$ P1 J+ k: W% w child=None 2 [7 X( g) b- Z4 ?" Z% b2 l parent=node.parent ( ^5 Z$ }+ d( I- x color=node.color 3 z, L# r0 ?8 J3 Y) |3 Z if child:5 i- w7 p. ?. C; `2 T
child.parent=parent: q- |. x; d6 {% W
if parent:4 i) g( W8 e8 d" s
if parent.left==node:" m$ I- Y6 w. I, C
parent.left=child) C. ~& Q4 T. Y% v
else:9 Z9 K3 l3 ?3 l$ t3 m; f
parent.right=child " h- }" C1 i5 y else: 6 c; T3 N: Z: p5 R self.root=child( P% }9 i j; E. @
5 v% v; K7 ~" m if color==BLACK:& ?0 p& T% c/ V% s* o
+ z3 f* Y$ t z3 j& c# V; ?7 @" I self.rb_erase_rebalance(child,parent) ( Z. j: I! P, l- \9 r/ Q' h; f. p8 G
& _" O. |2 P B5 M5 V, z* ?" B
def rb_travelse(self,node): ; s* A" M) w/ D if node is not None: 6 O+ n9 N% }. L3 a7 i/ C$ S" y print str(node.data)+'\t'+str(node.color). f2 m% u; p( u' {, e
self.rb_travelse(node.left) 1 f& O7 x3 {" L. p3 s" B+ g if node.parent:. t( \, [. K- {+ g7 n7 h+ R2 d% p1 l
if node.parent.color==0 and node.color==0:. D* ]+ S! ^7 w- J
print "error"* Z8 X7 k( R* H9 N
return ) `' D7 M0 x/ G# |( w self.rb_travelse(node.right) ! c, j. c; [# N: r* c; h( K" f if node.parent:- S6 ~/ w! b6 W: j% s
if node.parent.color==0 and node.color==0:3 E4 N2 x/ z- w0 u& L1 ]
print "error"8 r4 y2 T/ e9 D, V# W9 A- D
return& c/ b3 b# I# N) w; r2 R% m
1 Z4 h% }1 U5 v return 1 l5 D2 d% K6 x# a7 Q/ {' C& f 7 X" x, _4 d4 c9 r1 F6 X9 } ' m" _2 f+ J- {! Z2 v9 j
def cmp(self,node1,node2):" X7 }( M( C9 I% i4 X# Z8 R! U
if node1.data>node2.data : % B, ]1 _" E4 v X return 1 ' b2 F$ J7 E( s* x9 j if node1.data==node2.data :( _$ F U7 Q8 I
return 0& Z. u2 I, c, [8 Q, e& @4 v- f5 w
if node1.data<node2.data:% J, p% s1 e Y5 S) N( `
return -1 8 `4 Q% m4 m# } 7 L2 L. O& B+ b& K3 z' Vif __name__=="__main__":! G9 X; s0 I" _. T2 l
print "main" H1 [) \3 g: C. ^# m2 R$ D/ k
data=[28,6,39,78,6,43,61,56,71,38]2 J! M( e( n: Z% r' ^
#for i in range(10):2 H3 f. j" X$ E8 ?3 w/ z
# rand_num = random.randint(0, 100)* h! T5 m: S: K3 H; \3 o h% x. `" P, w
# data.append(rand_num) 9 e* |7 y: p2 @3 [4 q #print data5 T& J0 w) Y9 J+ c+ j* r3 g; v
t=RBtree()2 Y; A% X, }8 Q1 p7 i
# K j+ k' F: L7 J5 L) y% G; |5 m7 p5 q8 \1 E
for i in range(10): ' V: ?! m& ^1 V4 y! P5 Q t.rb_insert(data[i]) ' ^) j/ Q7 D0 l 8 S, g6 K, `) A( h) y* g; n2 V) w/ Y2 }
t.rb_travelse(t.root) $ c4 Q" J7 D1 T2 B2 V& F/ |" K* h1 h$ }! J# F4 m* r( Y
print "---------------------------------" ( a _, y; B4 J4 e6 w5 o t.rb_erase(data[7]) 6 ]3 I' `$ d5 \ . J; I) D7 N1 M- X( j+ R
t.rb_travelse(t.root)$ f) o1 h# w/ {, @4 b
# }' B; k0 _# m" f( S% i7 t$ [