; t9 I2 Z5 A' w6 T# R; X, b node.right=right.left 7 C* a0 H2 e# p3 z if node.right is not None:- V) G: J3 v, k$ m K2 v
right.left.parent=node : x( q8 f O4 ` ( b" f. r E" g) C- V& w. z right.left=node. r; P/ r: \1 ^5 b/ {$ H
right.parent=node.parent ( U# X3 B- m/ P, W+ G. r 2 Y8 w/ e: f: W5 G. I9 S if right.parent is None: 0 f. G( [, F6 ~+ J: O; x # c4 z/ c6 y' V
self.root=right1 b5 s7 L1 G0 D4 H1 @
else: 8 E! _/ ]: W4 {: `0 k. a& ?+ D! I# T if node==node.parent.right: 3 Q& g0 P5 a$ c/ H node.parent.right=right & F L+ J- N: a' Y: u; c9 A3 o X else: ! a" q7 L, ?& C. n8 d) \) d( m node.parent.left=right$ s% n5 ~) F2 k8 N6 d6 z: |# f$ A
node.parent =right - X+ g7 j/ t* ?0 G5 x+ q# q% O' h* |' }, v& M, o9 F& U9 \
. ~1 ]8 d3 H" M3 h* J
def rb_rotate_right(self,node): 8 s; \: `* @$ |" [+ F+ J left=node.left 5 n% t+ V6 Z4 U$ B$ K node.left=left.right 0 z5 F% r0 u% [! _, [0 F* H9 J, x+ X' M* g
if node.left is not None: # }$ A2 Z* t+ C left.right.parent=node 1 Y @& P# B1 V# Z+ w, V + q; @8 Z$ r# Z& y left.right=node ) R% t9 o0 ?" ?) [ left.parent=node.parent & P! o% w, G% n h 9 J8 H: U2 X( L& } if left.parent is None: 0 i4 O4 j' `8 P3 H self.root=left / l5 p1 ^4 G8 D4 U ]8 u { else: 7 F9 m8 L! `" E; u: A O if node==node.parent.right: + l5 O/ p" M. H- v. T8 b3 Y8 \9 W node.parent.right=left6 |) l9 v8 A7 G/ O6 C. P
else: , t# ^5 I- s' B- {- D6 T node.parent.left=left 4 L5 O# c; R Q% Q" @# B* C node.parent=left" d6 X) B; M7 r, M
( A& G8 u6 P% |9 o
def rb_insert_rebalance(self,node): : G9 \3 N8 g0 ^, @$ s2 k7 h parent=node.parent % i& i- E" k/ j% n: ^2 a$ ~8 g while parent and parent.color==RED: % D' F! U) J* R+ }) } gparent = parent.parent & B' e- w8 g! _% Y: |7 O if parent==gparent.left: `3 ], ~3 H8 D2 u, [9 k) o
uncle=gparent.right1 t! Y& _- t3 C
if uncle and uncle.color==RED:- ]# u' |' T$ m1 \& \* }" h( ~( I
uncle.color=BLACK : x2 R: `( x9 V8 U0 ~' z: ` parent.color=BLACK1 |3 u0 k e% [+ o7 T$ O
gparent.color=RED 5 |( _9 c+ w* ^' g node=gparent 1 n. {& f" j( Q/ e0 C* X else: " I+ z3 {2 i$ J- \) t" s& d: h if parent.right==node: $ [2 r1 Q, t+ \# }! N7 n self.rb_rotate_left(parent)# |0 b! H6 P) A$ i* h
tmp=parent 6 n; A/ B$ g6 c7 d" C$ z* r9 n, j7 w parent=node' c: e( `) @& N2 f, Q4 N) G5 I$ O
node=tmp* z: K- d& v* x) b% A& o
parent.color=BLACK j, O ^* D- {$ u8 w" C5 R: e gparent.color=RED / i Z; z/ f) {/ _( t& ~2 G9 p- C2 j" B# h" y
self.rb_rotate_right(gparent) 7 k" M0 Y5 f9 R* q" D: _% h( X5 i" y' c0 ~
if uncle: ; k' N. W' C |! \1 e if uncle.right:' k9 J+ i2 y& r5 h2 P
node=uncle.right" M2 G9 n, p5 O
else: % Y9 P: ~7 `! p% b$ I uncle=gparent.left% W. a9 u$ k) p. O( ?1 ~5 ~# s
if uncle and uncle.color==RED: - \# T K( U+ l; x9 I: v& [ uncle.color=BLACK) ~0 m6 {3 h- E, U
parent.color=BLACK 8 M f/ x( P8 M gparent.color=RED4 o1 g# y: b& e. } b6 W
node=gparent ) h3 _$ Q6 T% | else:+ m ~+ L/ i) ^' o& I' \* p
if parent.left==node: & y. M+ v! D2 [. T; w6 [ self.rb_rotate_right(parent)- y t) P1 o$ \' y" v% {
tmp=parent& `/ P9 K# S+ Y7 G# Z
parent=node w" u, E* o6 Y0 w7 M
node=tmp. G0 h; Z/ A. R
parent.color=BLACK ) [# K! }# f+ }3 G% J% Z2 G8 u gparent.color=RED 8 _5 Q J8 {$ [6 s self.rb_rotate_left(gparent)5 b8 d& J, I8 N3 n
+ P V% s/ M! s5 j0 z) ? if uncle:4 c3 H# |: X5 a" u
if uncle.left: 2 [" H4 U/ P/ y: ?6 J8 y, y9 s( U' l node=uncle.left; S! n# A( @8 o% s5 R: x, Q
parent=node.parent$ @8 H9 f" \/ w/ z$ W( T* F M
6 W9 r" I; ~9 f8 y- D+ n ; ~1 q( ]. V$ u self.root.color=BLACK3 v3 B. V8 X, t0 g
, o2 M/ N' ^8 }) s/ c# x
5 I: n8 ]" ^1 _0 b& H
def rb_search_auxiliary(self,node): 4 [3 F9 d& m4 {; Y+ L tmp=self.root 9 K% z V3 S) y+ r, f+ I parent=None( g4 F% Y3 J- z8 F6 E
while tmp is not None: ) I: k( w& M- D, a' W3 G parent=tmp $ ?6 L% R2 H: ]1 t$ B" A! |3 o cmp=self.cmp(node,tmp) f/ s9 H6 B; Z8 T4 P
if cmp<0:" A% L) _$ V& i
tmp=tmp.left / s2 I7 i i; }4 n( c2 e% H. _* B/ N else:- |: N! Y3 a$ F0 K) L6 f- `; i
if cmp>0:5 e$ G; }) p2 k
tmp=tmp.right# {5 G0 Y" v, G
else:1 I% h& A* P. _# X. r( E+ R- m% C; n
return tmp,parent6 E. C4 {* k) J$ M, `" @
; b8 i& q* S E: J return None,parent- h8 Y3 m) A5 Q9 R
@- B9 r- l; i# {! Z. c3 _$ c def rb_insert(self,data): # D6 Z; |0 s. @$ |/ e9 R tmp=None ; b- E- H \6 y$ {# \+ h* _& D2 L. d* p node=Node(data)- Q8 {! ~5 F3 l/ W e/ X
tmp,parent=self.rb_search_auxiliary(node) $ A( z, B, `) S( ]2 f4 _" R; U% m( B
if tmp is not None: ; V6 ^! O7 c3 a1 O& d return / _4 B; J4 M6 q1 f
3 X5 ?& P. K0 L5 \' m% @ node.parent =parent3 B% P- E) o2 l. j0 {- Q. I
node.left=node.right=None 7 \1 ^) |$ K. e% T7 D5 L node.color=RED 3 y7 z% h2 W( Y4 \; M n8 M0 J- e
if parent is not None: K7 H; G k5 t0 ~$ m
' F( x. {' M1 I if self.cmp(parent,node)>0: - ]+ m1 a1 Q: B, }. D# C( E8 g parent.left=node5 K7 z% i( W+ A$ n: F2 g6 i6 z
else: , y0 e o$ F+ q parent.right=node ) \, L' o& B/ s; z4 h* i else: 1 l% ~$ i1 J9 [) J- k; R+ ] self.root=node% y: r, M7 p! u
return self.rb_insert_rebalance(node)7 z- D! Q* X& E% J3 Y) Z) Q
+ W2 s6 ]" e8 r! ~
def rb_erase_rebalance(self,node,parent):0 X* Q3 r) V5 Z3 K
while((node is None or node.color==BLACK)and node !=self.root): 8 `1 G7 Y5 s) w- y if parent.left==node: ( a" f8 ^8 B5 C/ i7 m7 S other=parent.right! B0 P9 T; B: O6 ]. F9 x2 i; U A6 L
if other.color==RED:7 b) F, N( T+ l: C( ?
other.color=BALCK% Y4 N4 Y# P4 `/ J1 } f% D# s) U
parent.color=RED # S, _4 n- h# X" E9 r self.rb_rotate_left(parent) / G% P& I9 E% {/ S other=parent.right / w! e O% ^4 h$ U* W7 ?9 R/ q if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color ==BLACK):; j5 e) O6 w k
other.color=RED. E: G0 d* n' M6 L$ j i& ?# h
node=parent ) i4 L5 H" }5 M( W0 h parent=node.parent # D$ u4 q; A8 X3 @9 n else:3 i! X* _9 h4 w* {6 {: m
if other.right is None or other.right.color==BLACK:+ i9 n; H- V; E% M4 ]8 w" ~
4 `+ \3 y* y) V+ X% ~% c4 p
if other.left is not None: $ g; k4 L/ V1 c( M other.left.color=BLACK ( I9 ]% E, S) i other.color=RED ! X( X G5 K5 c1 u- s1 g self.rb_rotate_right(other)" ?; J4 r f# m- D
other=parent.right V- F0 z3 u, _0 `+ b* f9 _4 [+ ?( ~& ]" i
other.color=parent.color % L7 n7 }9 N, k+ p+ [ parent.color=BLACK8 D* Q' e/ C/ p1 f1 _
if other.right is not None:0 R, t9 w' C- Z. j
other.right.color=BLACK . `" l( p8 W; z! @: t3 i self.rb_rotate_left(parent) * u3 t! O; L) N' f node=self.root p& L7 }& N" B5 m7 V break) T1 o/ l6 b8 y2 V8 J
else:+ V+ A( n$ U8 S4 R9 N, _
other=parent.left & y- i8 |: k$ ~ h: f& y7 g$ F6 \ if other.color==RED:6 A6 o: Z! s# Y" c( V! O
other.color=BLACK % |+ w5 q, I2 r' t. R+ ?# m parent.color=RED& ~) {. E! m! J* j) }
self.rb_rotate_right(parent) ! b' ^% k! }& u' E4 t other=parent.left1 F+ n+ O- {2 w
if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color==BLACK):. C Q7 u, ]. {
other.color=RED 3 N$ F" q& _$ R! o8 G- F node=parent 9 L: _+ B3 ~9 b* j: p. C( I" y parent=node.parent 9 K+ j3 i- v7 o/ P6 M7 R else:8 U- Q% U k0 V
if other.left is None or other.left.color==BLACK: % R! S; Q1 V/ p4 G; L, b if other.right is not None: 1 P* k" K: A( G- n: f0 d other.right.color=BLACK/ o t6 A, Q& v. A0 L* ]' r3 R
+ H+ ]9 k$ H! s7 w( m. u
other.color=RED 2 P! K! U5 w4 p1 O self.rb_rotate_left(other)- p) p# v, \0 n/ K9 r1 p' v
other=parent.left 7 {8 X2 M; N- H. i5 r) a3 M & v# x8 T# Y) ~, O( @ other.color=parent.color4 p; Q# D& W$ j+ N- \5 f0 _+ M) j
parent.color=BLACK 3 ?; J& A. u0 I$ n9 C 5 }- ^: w" r9 ~$ b4 [# H7 c" ]1 L if other.left is not None:% g& Y( T- x0 l2 R, P4 m1 Y! z
other.left.color=BLACK4 o3 W b- b6 Z, W
! p( ?' @) ?0 v# |3 m
self.rb_rotate_right(parent) : T2 L( i% i9 Q0 Y9 f; L) q' H node=self.root ( x$ J- U! i- G t1 S break$ |3 N+ B0 n/ y
7 d5 ]: ^1 Q1 O( M& K+ O9 c5 G2 ]4 y- n( W2 W
( x/ u2 j: |, a% j2 u. p5 c. ^/ b if node is not None:% G( h( O& ^5 d' ~" B' @
node.color=BLACK 9 q9 w/ M8 @9 G" @5 s5 Y+ l0 v
! u' Y7 d% y" _2 z# W0 G- y def rb_erase(self,data): * L$ y4 `$ R1 k) B8 r v tmp_node=Node(data) " ?' ~0 _- T) c @ node,parent = self.rb_search_auxiliary(tmp_node)& b$ z3 i: X' ^, a
if node is None:3 e8 E5 D: D9 R! G0 J0 P6 s* z$ y
print "data is not exist."/ x' P! @: T0 |- g. V! l2 _
return & d3 H: i+ W; P 9 E% }3 X5 R; J& M" C: n old =node $ Q* b, W0 m3 \5 ~ if node.left and node.right:+ ^, g" p! `5 N! h, ^* A& M
node=node.right : J4 i& Z$ B2 \7 b4 G 9 M5 ^: y& w9 X7 }" `3 k left=node.left$ B, f5 k9 d% B
while left is not None: " c/ [& @5 |: P! ~# U8 w2 G node =left $ O9 J/ Q% H6 |, j( l left=node.left ! s, K/ M( ^0 h7 L! [! L' r r2 y6 I5 V' g2 q' x! E$ @ child=node.right7 _ {" a5 i' x9 Z
parent=node.parent* y* l: g& R& ?% S2 b& e2 p! Q
color=node.color1 r2 V3 J+ o" ]3 E1 W3 x q: D2 A1 Q
4 Z( }4 _( W: B e2 Z2 P+ F if child:3 H8 A) ?6 e0 z# t
child.parent=parent7 d3 u' K* [# T5 u" b8 n+ _
if parent: m/ d/ X4 [8 {# z" H
if parent.left==node:. {5 |4 \# Q! g. i( i- I
parent.left=child) T: N' b! [9 p4 M/ L% u
else:0 G/ Y- T3 v" G" D
parent.right=child 7 t- w: ^, W/ u0 y2 k' q* H* {% Y+ g, r* m, a' V
else:# o6 ~) b( h0 I
self.root=child : w& g& \5 S8 a5 b! T* ^( h5 V. ^1 ^% t
if node.parent==old: % T/ d' ^* [! E* \ parent=node W/ x7 V* A4 W1 c" o% | node.parent=old.parent 2 j, q( c, L2 O7 @2 [/ c' L% @ node.color=old.color 7 O( ]3 C& n7 l n6 n node.right=old.right7 H$ Z# @6 d0 o6 k
node.left=old.left : L, W% d9 u/ o% J; l ' T* l& ?8 V- O+ R6 A if old.parent: " L( \3 f9 i0 z, V( D" N if old.parent.left==old:) n2 r4 _/ q) I
old.parent.left=node 2 ?% q! {: x. |8 y" U- I else:! E- u, S5 y8 V. @: [8 A
old.parent.right=node 0 B0 d6 n# q4 \( } else:$ e; P0 z- t2 O/ c: e6 b/ u8 E0 g. u; v
self.root=node 2 X6 J7 c; u; C5 n # Y+ `- C) \8 Y! V t old.left.parent=node# y7 {$ o& i: O( _. F9 l0 c
if old.right: $ U* {. e3 z# P; i! ~, q" E old.right.parent=node ! f6 F3 x6 i: U5 Z8 e ( {# S2 G6 U1 u3 N) T' W0 ^+ r else: 7 u2 g9 U5 ]1 Y' K! ^0 ?, h% d: G. Y if node.left is None:' b8 Z3 t5 W' D& ]. j
child =node.right! T/ g& T' P/ e# |, A% O
else:% G( U6 U' V; a
if node.left is not None: 2 `, ?- k- q0 T( n$ E1 [+ o child=node.left9 |! Z2 I# w% E# H
else: ^" ~. P* L" O! a0 }$ D$ o
child=None 2 s* k; Y5 N$ j$ k+ U/ O. K parent=node.parent 5 c/ X" O7 m, }" t3 \* \ color=node.color# R% `6 _& S% j/ x% W9 e
if child: & m, \+ S5 h6 `# I child.parent=parent : S" S# ?, c- `& B( d& S# q/ u) } if parent:& |4 K0 f5 a) f7 g( [
if parent.left==node:: g% R k p/ |6 o9 `) ~! b
parent.left=child , Q2 B1 S4 D+ d' E/ u else:# U9 C) X+ e5 c; _
parent.right=child; P0 L" P) [- u# B+ I. B
else:! ?; b/ i4 u. x& m V9 M2 A- d: ^
self.root=child 3 z! H& A. p: g$ N6 T- Q# K* {* S* x, H( N0 M$ f
if color==BLACK:. D0 ]- E( [" U {' a& L
! T* G6 { z; x, p self.rb_erase_rebalance(child,parent)" \5 U! {0 S1 O
. u% _; f. D: l i2 c$ G9 Q. S' o & s5 c2 Q! a6 S5 {* \. I def rb_travelse(self,node): V) H2 ~3 b8 a) \: e. O if node is not None: : s( s1 C) x. q' | V( f9 W4 Q print str(node.data)+'\t'+str(node.color). _$ [+ v' X7 e8 o4 ?
self.rb_travelse(node.left) , L% C9 P! R' h& Z; B if node.parent:- g. ^, v. A- ?. Q3 c
if node.parent.color==0 and node.color==0: , D# O/ H" _$ g) E1 ` print "error" # o9 [3 @- B F( E" }' j return + {1 k! M9 i& ]1 K9 |: a6 n self.rb_travelse(node.right)( {: H1 Y% F4 _' |% [ b! @
if node.parent: - U. ?) F/ A2 r: c# S1 q/ G if node.parent.color==0 and node.color==0:4 _1 Q, e4 F0 M1 J
print "error" ) Z" b: n6 ]4 H0 I# D return/ w) J! F: N. G# Q
% H1 d- r# g3 R9 }1 z1 ^8 u3 U4 @ return , r$ `' D1 s( k* R: e$ u' Z" S ! F4 \# |! z) K" |$ X% @ i3 F * ^! z, D$ A- d- H3 E
def cmp(self,node1,node2):- [1 Y7 ?3 | q1 N. L6 _
if node1.data>node2.data :9 n& q' z0 ^/ S
return 1% [' ?5 T3 v8 v2 F4 N, e
if node1.data==node2.data : " v! |- w7 W1 C' t) w; n return 0" e H1 C$ T6 E" Z8 z! L$ ]
if node1.data<node2.data: # L' B6 g- P3 i. K A6 S9 B return -1) {# r0 f" b) B! L$ |- w. B0 T" [. j
/ Z5 M9 U2 J$ i0 I% J
if __name__=="__main__": 7 T: ]; L, \- T. d) R+ }: J+ I print "main"% E* x/ S2 O+ ~0 {$ y0 z
data=[28,6,39,78,6,43,61,56,71,38] " e4 L/ B: d5 y0 m+ b1 e. g #for i in range(10): ' |4 g! |& d3 u2 ` # rand_num = random.randint(0, 100)) J8 y' v' y. M" e& ?
# data.append(rand_num) A7 ?1 v v3 V& j6 l1 W2 A/ N4 h #print data7 n9 {, C$ g/ x4 g2 Q3 |
t=RBtree()/ L, |& V' o7 W1 R
" Z3 c& F0 h2 }$ b+ T1 d
: X; m! ]' Y- ]. @- P' b9 \$ Q
for i in range(10):$ x: I0 K5 a% Y
t.rb_insert(data[i]) , g3 N9 k! T" I0 `: [. s! Z& ?& y& A
8 v3 l) Z/ ^. d2 [( d! s- j t.rb_travelse(t.root) ( p/ ~/ y$ J) N+ |1 M $ M$ X6 Y8 S8 v print "---------------------------------"$ ]8 D$ V( u8 ]1 ]: G/ m3 R
t.rb_erase(data[7]) ! V( I) p# k% ^4 M- _9 j$ ~5 l" W ( {$ j4 j7 s9 Q& k8 O8 |# Z t.rb_travelse(t.root)$ p; }* b- U2 N: k/ D$ V
) D0 v% o4 I m' D1 e4 N: h& ]; {