- `+ c) c+ \6 c8 m5 Z" m' O' d if right.parent is None: ' i) h, J' c( T4 s n! ?1 e & Q2 y- p2 n8 J8 \: Q
self.root=right " D+ y9 F$ r1 O, F1 e, O/ s else: ' G) f k; G C$ {* R! a; r if node==node.parent.right:: ]' V3 S$ V/ _5 X3 P, o
node.parent.right=right $ Q$ w5 x: x: O) _ else: 5 Q. |9 S$ ~$ V6 y+ ~) B P* ~ k2 k node.parent.left=right! D4 D5 j( w" D5 J" @* p y0 {
node.parent =right3 f7 t Y- Z: \
, g! @+ Q. y1 w; N" X7 J% R3 M3 i( H
7 G6 `, h9 g( K. ?6 a
def rb_rotate_right(self,node):* N" m7 D4 A1 J/ h
left=node.left 6 O8 A2 U$ Z$ E( f1 c node.left=left.right & q7 ~0 y" q% M, v. }; n+ U0 K3 |( t9 Y+ I) [8 U( u
if node.left is not None: ) A, G! l/ V; h; J( I8 { left.right.parent=node ) Y5 }$ S9 |( k- j: ]! B3 M: b# _& e6 _ 9 m; w4 L3 D7 c# }' c) T left.right=node - E6 V# y. k; ~ left.parent=node.parent% L( Z9 a+ b4 C0 H8 T7 v6 K
3 ]' z2 p% R( {+ P: j, o! V
if left.parent is None: / _( t( g r2 a: { self.root=left/ H L+ C' t* l. a6 m) d
else: ( R' c" N. M6 _ j if node==node.parent.right: $ o+ v8 @; }# U/ {/ A node.parent.right=left ( [7 d( T U P: b. ^$ n else: $ G+ f3 C6 }0 K2 ^3 ]% t2 e( | node.parent.left=left, D4 @# x0 v' g3 h/ z3 m
node.parent=left; u. ]5 i7 \& B) z9 S3 n- N: y; u
) H) G/ `: r( e- x- `
def rb_insert_rebalance(self,node):- p1 v* R5 @: I) j+ |/ Q
parent=node.parent; v7 }* ~* b' `* M2 ?( E
while parent and parent.color==RED:# t0 q* V3 f- i( Y- e
gparent = parent.parent8 [7 N) ~7 J; B: S0 h" L
if parent==gparent.left: : n% V a$ U9 A" J3 {4 I: x3 z uncle=gparent.right # O; ]+ Q0 p& w if uncle and uncle.color==RED:. Y, S- E1 B: t# A
uncle.color=BLACK \* G4 ^& ?( W4 Z
parent.color=BLACK. C0 n8 S# O+ F. d0 P
gparent.color=RED ; q) i4 |0 u/ s Z; n node=gparent 0 w9 f; i, G5 ~, D6 r else: # N0 g; F! {7 E/ J. o7 \ if parent.right==node: k9 ?3 W/ L& k! ~. l self.rb_rotate_left(parent)- ~/ L& O+ Q& A* G
tmp=parent 0 a3 R5 N" `4 r1 Y parent=node ' m# S; X( L/ v node=tmp 0 a* u; j; A8 B; k9 }& m parent.color=BLACK ) Q# ^1 s* \% |2 Q+ | gparent.color=RED J6 x; j3 J$ Q$ e3 J _6 h e' k) l' t1 U
self.rb_rotate_right(gparent)! w6 n+ ~7 u: O9 e! V
; s$ V2 V! K' @) L- H+ o: H
if uncle: E; H/ {+ @: H4 ^% w+ ^
if uncle.right: ) j2 u& h! k2 ]( V1 t node=uncle.right / Z. w& T3 [. y |; G4 i( R else: 9 o8 t+ @: q" ^0 U uncle=gparent.left" a% s5 k3 D5 d. `! c9 L/ X3 B' @
if uncle and uncle.color==RED: 1 ~* N; Q; I* N% {" C2 _) m; N uncle.color=BLACK5 W$ H9 `2 C: y, X# d4 Z
parent.color=BLACK ; x, s& T, H/ G1 X! Y gparent.color=RED% z l# j1 U9 n+ ~
node=gparent 3 Y% ?5 o3 s) C else: " Q. \5 e1 b) Y; Q8 Z if parent.left==node: / M1 Q- {. \/ U/ v* P self.rb_rotate_right(parent)$ u! b. {6 u' G9 f/ J6 k
tmp=parent8 m) ~ s* R9 S9 w. U1 S7 i& U, @
parent=node, J: Q. u6 u7 D8 M9 J# e( a' o0 U2 Q
node=tmp * `! N2 X' f6 O. k parent.color=BLACK' {2 c3 k+ L( B6 P V
gparent.color=RED; u- F2 ?2 n5 h6 P: ?
self.rb_rotate_left(gparent)0 P( P. T# Q% L8 `9 Z
- {: f* j" j( j* N if uncle:0 D% G- E. ^) ~
if uncle.left:0 I; \9 G% }* i4 L7 N6 d
node=uncle.left * G! T' [0 w9 H& f8 s( N$ O parent=node.parent; V3 T8 b" Z# ]& N: d$ Y" n4 X U: r
) N7 L: l* o6 G 5 \ B6 ~; h4 i) j# t self.root.color=BLACK " x% r+ P2 g: m2 Y h: ? n7 h / \; t5 {" _# O" B 4 I9 X$ Q6 m0 G- b. G: j' @( d
def rb_search_auxiliary(self,node): * f! y7 O1 `* b, |$ t. f: T( J+ z tmp=self.root( ~$ d2 I+ A" `9 f
parent=None % p, r7 I! e% h$ I# K! Q% W while tmp is not None: 6 z: N. e* }9 r5 W$ j parent=tmp T6 W* Z f" ]0 P4 @) L
cmp=self.cmp(node,tmp)% R6 ?( N0 S8 s0 X
if cmp<0: 5 G; V& S+ t r, m( {8 g% ` tmp=tmp.left/ h, S ^' X" I6 W5 E
else:# O6 L! f7 C; G) J) o, R# ]0 \3 o5 L
if cmp>0: . J3 I1 A; k1 h1 J+ [' A: U4 j tmp=tmp.right) ?) Y2 G4 a- }, u8 t" m
else:- G5 ?8 I( a+ [0 @; P: G
return tmp,parent0 J! X) K! G g) } M# _
! c& A3 p8 H9 R: U6 `9 \& M return None,parent # s: O) p5 X$ W$ c5 ~, t. ^7 K* Z' O4 b' H' J/ _: j! f# @! ~, t
def rb_insert(self,data): ; Y b2 h! U2 f2 w/ X- B tmp=None - ?/ G2 C% M, q' D1 t3 H* g& i" F node=Node(data)0 F& u& G4 [3 z$ Z! X3 T
tmp,parent=self.rb_search_auxiliary(node) & W- M1 v. r6 j8 Z5 F . W0 e/ q2 A c0 K# ?3 U if tmp is not None: }0 X) e6 p: ^: i, G2 x0 @# t return 7 z. W: j2 [) X4 E 5 ?6 K, a4 @+ m2 F$ D node.parent =parent. k# Q @, L @9 a* s) R: F
node.left=node.right=None$ C# f( ~7 H+ S$ @+ x6 W
node.color=RED( F3 f. P* B( v+ R
$ V3 ?! w- p3 f4 ~' [* s1 V) x, E$ a if parent is not None: ; `4 {4 N _9 E. t' K- E6 a 7 h" `- J! N: {' q( a if self.cmp(parent,node)>0:% T% a- Q( R ^: I- E" L( c
parent.left=node* B9 @" b% m) M: p }7 y
else:5 m- U& G$ g* L0 U
parent.right=node! V# n& ?! y1 V% u
else:4 ~5 U" E8 |- W. E0 s% z
self.root=node; B& n S, t' `+ v: d0 U' t& j& T
return self.rb_insert_rebalance(node)+ U3 `: I* `& y6 `* n
: L- k: B8 K/ c def rb_erase_rebalance(self,node,parent): . v; {+ u2 ^0 G1 R" c& X+ g while((node is None or node.color==BLACK)and node !=self.root): 0 p# c* R1 a, i+ L0 P1 R1 v$ X6 \ if parent.left==node: ) D, e7 ?0 [, z. P' j5 j; V other=parent.right . M/ `& m9 f; n, V if other.color==RED: 3 O- ^ s/ P4 j* j) }: z- n. B other.color=BALCK, W& W6 n; z2 `0 o: [) { \+ G
parent.color=RED3 o6 k9 _. v9 j) v
self.rb_rotate_left(parent)2 |$ W3 ]4 X6 x6 r
other=parent.right# ^" u5 F4 {) y" \ q; y+ }
if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color ==BLACK): 5 q; v6 v5 b5 W( L z; ~ other.color=RED 3 Q D- r! C* x% X node=parent 0 M4 p) ]" k* H! G* d4 _ parent=node.parent9 m7 Z( {0 m! G$ H/ E
else: % A. R/ W+ S' T' a, j' q if other.right is None or other.right.color==BLACK:0 e2 Q7 g% I- w! i1 _* y; \
5 p- l' O7 p9 R if other.left is not None: ' a @! _& j7 h Q2 l other.left.color=BLACK3 |4 ^& A4 N: U& J: d0 F
other.color=RED - P3 K" H6 J4 |- A$ s self.rb_rotate_right(other) + _. \7 L; J/ r( Z9 `! E8 f; W0 u other=parent.right 7 B# w" D/ G9 P9 v9 x" X 7 h- b' O4 W- u* l: v! H; E% h! L) e0 D other.color=parent.color4 c1 p" H6 k# q, u& n7 A# @* }
parent.color=BLACK7 G1 v6 c0 Z) t4 _; _8 b! l1 l0 U
if other.right is not None:; O7 v9 u" n0 _' ~& F
other.right.color=BLACK 7 Y' U5 w1 O n6 b. v9 @ self.rb_rotate_left(parent) ( l: P1 R8 w; A& m node=self.root' ~) x: g/ W! }; h4 w# A* ^* v
break & ^8 O; b, W) l1 Y { else:6 h& S4 G; c" f
other=parent.left 1 T3 u% i- U0 s! u if other.color==RED: ' P, X* h H: o( y8 m' f other.color=BLACK ; k* T. \* ~) M parent.color=RED : r$ |# v8 V* i. x& Q self.rb_rotate_right(parent); v- ?, F& H9 _9 y @* _
other=parent.left! \& V* I3 ~9 O/ ?! e0 r. G- {
if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color==BLACK):; r5 O) _4 O2 Z
other.color=RED# a/ C" U' V( o/ A1 l
node=parent5 t: r9 H. [! a$ x2 a# k8 D8 A+ H
parent=node.parent, ]" C1 R `- G4 X) [
else:! W1 C, w; ?/ |$ p
if other.left is None or other.left.color==BLACK: ! d$ o5 J% _+ z if other.right is not None: % _5 {8 V! d" H6 u0 f5 Z other.right.color=BLACK ' O$ n! c6 W" Y' t' J" M . [+ a5 ~2 N* _0 j other.color=RED 2 F0 v" X, f6 F1 |) x: M self.rb_rotate_left(other) ; h: _/ F! Y3 Y0 [ other=parent.left# e e0 Q1 O. n6 ^6 \, d
$ Q$ ?" ~1 l5 y& b6 C- v; V0 S other.color=parent.color. e4 T4 O; t$ o: t2 d. h
parent.color=BLACK# k, f. ~% z% t! c+ S" c
! L2 l- C6 D: {. P0 [8 [ if other.left is not None: ( s' I) _ p' D% ^ a other.left.color=BLACK; q& D$ z9 s: Y' ]
% t8 n, J# i7 [6 ~9 |3 v5 k4 z self.rb_rotate_right(parent); ` B* f' ]7 Z1 ~ `& s
node=self.root- C O/ W% e4 [: _$ u
break # P0 N1 O' W% a9 s8 ]/ M: F$ |! _; n- K/ S7 l0 n( g
0 }2 D1 g* f8 Z& _$ g e
6 `, A" ~2 ^+ p6 \( o0 I# g7 j* I
if node is not None: ; T: y( Y" Q7 N node.color=BLACK 8 o: L: s* U4 D+ C% W0 |( K; N2 G' p" w6 P
def rb_erase(self,data):9 ^4 D$ `- l7 s* }; J! h
tmp_node=Node(data), C) G4 E, M1 u1 t6 [: j' m P; s
node,parent = self.rb_search_auxiliary(tmp_node) 0 m$ ~* j/ q2 l6 u7 c0 G' I if node is None: & H& c9 ?0 j% o1 Y _+ M0 h4 d; L print "data is not exist." 7 y, ?1 t: q8 \; ^5 x return 6 c+ {) h% {) W* d4 l + _ r- A, w4 z/ P# P# c. L' ]
old =node - g9 `& a: }' m( h$ |9 B if node.left and node.right:$ D+ M$ b) S( q1 Z$ ]
node=node.right) h3 J, v. i: Z8 x. @/ Z# C* ` p R
8 U+ v& p* W3 X7 d; a& f: J
left=node.left 9 @. ?1 C, l' l while left is not None: 7 i* s9 g* u; g, V: ? node =left7 g4 g2 U* U# Q; v6 {
left=node.left6 A4 Y) c( z+ P+ t% P8 v( {5 {- D
$ `' ^0 _" @' C2 h5 @4 m3 W4 Y+ ? child=node.right 9 y9 D* f- Z7 H& P, { parent=node.parent y7 g6 O/ O$ P1 {: a( H& N color=node.color ) V5 V' g/ y0 J" K4 H# G, P6 l. g+ a8 C. V; R1 ^/ P; S
if child:% e( R" A( M1 a! Q1 ]; m
child.parent=parent 7 |5 l$ K; B* k+ A& m* T5 x4 w5 n if parent:$ w: v5 C6 K/ L& i$ W
if parent.left==node:* @ H, B" k4 X- `
parent.left=child0 Z' H# P/ ~9 L7 Y
else: : d* K. P& e6 o* v0 E+ E( U! M parent.right=child ]. ~1 ] W$ n3 m 7 L, r/ {& }) g5 N3 p) s" h+ r2 U else:- y+ l' E* `2 n. |
self.root=child j- O- D9 ~) y$ O T
; z) V% f2 j# s: s9 P
if node.parent==old: , W$ `2 ^2 [1 n' X8 v) Y7 a/ H parent=node 0 }3 E9 K, f8 G9 ?+ O P) g node.parent=old.parent & ]) n8 G: w, Q" k; i* [. e node.color=old.color: o( G6 N& i0 P
node.right=old.right % R- h- F" G/ V: ` node.left=old.left 7 [' p+ F/ w) u) G, F* Q$ x$ T" M* H) Z% b+ K; x1 v
if old.parent: % Y. l2 a4 W$ J# W if old.parent.left==old: ; |/ L5 I; i9 I( Y0 E; s old.parent.left=node : g9 m8 a; B0 K+ l9 d( `0 V% J7 X else:- p) e6 u4 ~, \" s6 y
old.parent.right=node H% n6 A V- ] Q9 _
else:! T+ K. n/ P+ ?" T3 o/ q
self.root=node - R* u0 y" a$ B' z& i! P5 J7 }
old.left.parent=node 6 |% R U; {0 b1 T5 B if old.right: + O# j% y6 T4 D+ f old.right.parent=node 5 v; a. B9 ]8 ]8 Z# y1 N: G v! n3 }6 u( Y- {$ _
else:# |$ Z* p/ l9 I
if node.left is None:6 x, O! h. t: k( Y
child =node.right ; h- Y, f: v- @; G0 B$ O. w else:4 W' D+ w) E i. \
if node.left is not None:( {" X) b& J( t* v3 G0 y
child=node.left 1 [* T0 p; N* \* G. \2 P else:+ d" j. u. q; y- T5 ~- P) ?
child=None, e% o m! E4 p; f
parent=node.parent % ^8 [) n5 E7 d( k j color=node.color ; R$ T9 M4 F1 j) G, l$ r! L+ T if child:4 L* T- I: N: _6 G0 R( `
child.parent=parent* D" C: h$ G: I$ E
if parent:8 `: c/ U; v1 E# e7 | b: Z- F
if parent.left==node: 8 N2 ~5 W' E+ [6 ~/ c, Y& g parent.left=child3 F# y: N) h# }
else: 4 N( B2 B4 Y7 V- t8 d parent.right=child, R$ z( @- C+ |- M9 Y( b- S! k
else:8 A" y' N; G: I
self.root=child + d* z! b; s) u! v3 r/ N- x v0 z2 r# z) U, t( L( X if color==BLACK: V( X" f, N. X4 X* l & G7 x8 E3 _3 r: R! t7 ~/ S t self.rb_erase_rebalance(child,parent) 6 w! `2 l5 e& r: ?, Z' S) t* K9 V. j4 s6 U5 g' Y
& o3 L; Z2 ?: n' n; j
def rb_travelse(self,node):' M1 A) n1 d8 b; \
if node is not None: $ j( f" J& L4 {+ O( L0 ?, e* k. b print str(node.data)+'\t'+str(node.color)* i. ]$ _ X' M8 Q) w6 U
self.rb_travelse(node.left)! i$ p, O! x# n5 J6 S
if node.parent: 8 B) c8 `/ P, _( Z) M) i1 u if node.parent.color==0 and node.color==0:9 X% }: }9 G1 h1 w# _
print "error" ' D$ Q- d3 R( X$ s% o return/ h. R) K. E, t& r
self.rb_travelse(node.right) : O y7 q C7 y$ H0 [2 b4 v# I if node.parent: : _4 y, K9 {) e% ?8 O; ^7 l; ? if node.parent.color==0 and node.color==0:3 U: r# ?; [3 {1 K$ v" B
print "error"" `8 E0 Z3 Y8 {6 A8 b' U7 ~: d8 j
return . o- r" C2 G* V( ?9 e2 r4 j5 K % a7 W& L* J; q- |, u6 y return ! `! O1 X% K# ]) g) k& z 0 h, _4 s, u: s5 E " V# p3 m6 ]% p' O def cmp(self,node1,node2): " j" | c/ ~2 G+ [) x* E if node1.data>node2.data :* [& ~0 A1 P$ c/ [7 L
return 1% U6 M7 W. x/ V! k+ u
if node1.data==node2.data : ! E( e6 b- ?& d return 0 + W" i0 U( R7 O3 R if node1.data<node2.data:, {. |/ n4 \! i5 |1 n+ \" x
return -1 / q8 u# g; f# t4 g) I1 i& b3 |: w, s/ ]; v; Y9 L
if __name__=="__main__":! q J2 I) q+ H
print "main"! D, ]' N: l0 E
data=[28,6,39,78,6,43,61,56,71,38]/ O+ b9 K* n8 v, @- q" o% m
#for i in range(10):) T6 Z* J% N0 o3 r. v3 y. T# A
# rand_num = random.randint(0, 100) , Q' n! s) p& l# h' ?2 E # data.append(rand_num) 5 E& l. b" r" v }, _2 d #print data - c) s, A2 }3 X. u0 _! ^ t=RBtree()( _1 x- E4 |2 |2 [
) m* C- ~$ q% G* y4 g 5 g4 k7 t5 j1 {( C# S% p for i in range(10): 8 Y2 G- O4 V" b$ |4 L; ~/ U) X t.rb_insert(data[i])6 p, P! _( y3 x& B9 a" F
& ]1 i9 e) `7 F/ s; |+ m8 c
0 V$ @9 z( o9 }, ?' [$ L" }
t.rb_travelse(t.root) / i& `' k! j( `' X' ^" ^; Y5 W* D0 Z+ @$ h
print "---------------------------------"( k6 m& T" x- U
t.rb_erase(data[7]) % ^- N& w. c$ Q- U , s8 P% }4 w- [( d+ ^; S t.rb_travelse(t.root) + A* _5 Z8 f' ]% m0 q; M, R ( P" C* c6 b1 S+ ~