& z7 S( @. y4 f5 `/ o6 W2 bRED = 0 ) s' g* f" c0 H! G9 \: o! \9 ^9 fBLACK = 1 4 g) }1 ~8 K }. z' }$ X/ a; M+ m; V2 s
class Vector(object): : t! E9 c9 R! e1 l- y' f+ r def __init__(self,x=None,y=None):; |& p2 |- J3 y \: I: v5 y
self.x=x ' f- J- R# w, ?2 ^) C! W/ ] self.y=y8 g8 }+ q5 n4 Q) }% i
6 c' a2 k% N) i0 k8 M8 E+ _/ ~class Node(object):' ?8 ]; U# Z( D- u
"""docstring for Node""" 4 w* r* Y8 a f, S def __init__(self,data=None,color=RED,left=None,right=None,parent=None):7 ]' D: P# _" a' \& @) ?
self.data = data: M6 ?$ j* ~+ |
self.color = color) C% g: } \: k$ i( _
self.left = left 4 A6 r9 R$ v4 E% s' m self.right = right : a# r; _4 n! V: w3 j- g" p self.parent = parent' K6 @& ^1 C, M' H
# U' H- H; x* A: q1 ?) W- a2 j
class RBtree(object): 1 G) p# f2 a8 J0 u, B, i def __init__(self): 9 g! `$ W0 F! Q self.root=None : [: Y- h, u. X, p; E7 N/ k" b self.size=0 . q' l$ r& }& Y5 k5 K3 Q , r9 V1 @& m; Z def rb_rotate_left(self,node):; h/ N! [+ |; b% D
right=node.right) k$ y' y$ Q6 j: R& G7 _1 R: P+ i1 {
& j# {& j! v! B7 s( m$ j node.right=right.left R7 y" I0 J p1 N8 F* ]4 l. { if node.right is not None:* `% N( E& M0 @$ n) ^: s
right.left.parent=node : w' A, k2 i! k2 E) K! A7 m % C$ f+ e0 O7 a; N% J' v& ?; l+ u. C right.left=node % ~( ]& u7 T5 E$ J right.parent=node.parent / s* C4 I9 e$ }$ F4 V$ ?3 c+ }' Z- {- T7 O8 {
if right.parent is None:7 r+ V3 L! b8 u/ M
4 N1 p- d5 k& w/ k" u
self.root=right7 ?" M# R- b- g. q. N. l. G* T" R! D& M
else: 0 [' f$ g) g2 W if node==node.parent.right:# ~) ?3 x2 Y' ]2 c
node.parent.right=right 2 ^) s# M+ Q- ]( k' [* [ else:' S0 u) e: [6 }/ }
node.parent.left=right. |! I/ G1 N- U$ S1 E: f
node.parent =right ! X1 i( A" M0 T7 O/ r# E7 N; ?0 f; [. z4 ?: V
* U) A4 N9 U2 U; H4 _ def rb_rotate_right(self,node):5 v- H. E9 p9 c7 }6 b4 c: \
left=node.left : d' L4 ?$ \ _) C- P node.left=left.right 4 s* T7 E% l- h d- I; G8 _( n/ v7 |4 w2 G2 e' N7 t
if node.left is not None: X; L" n( S0 ?! c4 x) t; M9 P7 g4 h
left.right.parent=node1 a+ h; C1 b3 f# I V! l8 R
: I0 s( h% u$ ~) o
left.right=node1 }0 a% w, t- Q/ d9 i
left.parent=node.parent 6 V- d* v j3 L/ j + \0 a! C- n# S3 G& g2 I" U3 W& ` if left.parent is None: , A& U5 C2 M. p" ?/ \0 B self.root=left& [: } k- _' W- [4 U7 \/ T
else:9 z1 U1 P/ q6 @. m
if node==node.parent.right:+ a" E2 b3 K' H: i, U" V; R! N( n
node.parent.right=left0 b: o2 o% W3 r
else: E/ I* j" C9 X: a8 S node.parent.left=left6 z, C' v U8 s( J
node.parent=left / l0 ]- i: q$ B4 U- _( b' w4 q . S7 c1 d0 l3 c- ` def rb_insert_rebalance(self,node): 9 g3 C* |1 v' E9 v parent=node.parent 6 Z3 i* z/ G+ T. R while parent and parent.color==RED:1 L6 G8 h+ G4 i) F1 \7 J
gparent = parent.parent9 _6 g5 U0 e+ j: [0 K+ w
if parent==gparent.left:8 B; N/ a6 u& d3 F9 H- ?
uncle=gparent.right * W: F% ~$ L/ V6 C: F/ ?7 d if uncle and uncle.color==RED: 0 G y! o- B( p% R: e N uncle.color=BLACK: H0 O, U/ g8 w9 N
parent.color=BLACK 9 b- d* }# B- A1 t gparent.color=RED0 P! Y4 `, K8 E- |7 Q, m# [( Y. m
node=gparent& i# e2 P2 P5 Y$ g) v$ Y- [$ Z- `% W
else: / _, v, w- q/ d; c+ u if parent.right==node: 0 M6 w6 _! q- I" ` self.rb_rotate_left(parent)6 @) f' w3 n i6 k
tmp=parent + F9 F- v& s+ ^" Q. L/ } parent=node' D: b% L: \# k7 A
node=tmp) s7 }' u2 ~% W* k6 q( b
parent.color=BLACK9 J- _7 j0 f- C& W, m; ?4 N
gparent.color=RED 1 N6 E5 M8 e$ T; B4 d4 M 1 {, h) B5 {& S: L: N self.rb_rotate_right(gparent) * R2 K* g/ }5 \ 7 a/ M) i2 p) u; _# w# B if uncle: 2 d! I: X. D7 b9 d. b if uncle.right:2 {% @" ~0 r6 p0 K" a) J( o" ^) Z
node=uncle.right o$ ^9 M/ J5 x9 k( c4 N
else:2 X( \3 C% C7 G" {
uncle=gparent.left " Y" `5 ?. N1 J; f if uncle and uncle.color==RED: 9 c8 z1 @& M( p. ]: B, R! G6 Q/ O uncle.color=BLACK# ]: M9 [* \* C8 \: ^' L( J1 v- F
parent.color=BLACK, S* g9 u) V, a# k0 q5 U3 M
gparent.color=RED2 A+ O2 Q$ a c& s. t5 B, I
node=gparent0 w4 }- y" z/ R# Q9 j: J y' w
else: 1 n, ]0 J% q% V; z4 Y" R if parent.left==node:, k* Q" Z, }/ V+ ~; t; K8 L# W
self.rb_rotate_right(parent)# X: e1 R( l6 }
tmp=parent. L! Y( d6 d3 F1 q7 ~/ R
parent=node e9 ^2 Y' Z4 D, k7 |. t l node=tmp/ G0 f a+ N4 \( U
parent.color=BLACK 2 b4 x& H0 [. O0 v3 r$ I gparent.color=RED " c& U" @) T- t9 n2 X$ `5 K self.rb_rotate_left(gparent) % i7 C- {" b& z( |# M : j8 _& c$ p5 H, s if uncle:' S4 F+ a. g1 m) {' v# ]( f+ ~& Y
if uncle.left: 0 Y/ l' K4 [% \: a2 R node=uncle.left+ X P' ]4 ~. x) d; h
parent=node.parent , _# H7 l' q" B4 m5 n ( e% g( H, [% {8 Q/ ~% c4 _( i! w5 q& a4 [) B1 f
self.root.color=BLACK + k6 z f1 c3 j + y( k8 R: w3 q7 l
! I! m5 V' E, }* l+ t* s0 Q def rb_search_auxiliary(self,node):8 N1 Q- V t; u6 Q, ~+ J
tmp=self.root. r5 Z' a# j7 V# x. A
parent=None4 _0 {9 r( V5 T& Y- k% g, C; G2 f; a. y
while tmp is not None:- d8 h7 n9 r7 c( J5 p
parent=tmp 1 r- m3 K# A$ j# u& ?- x8 ] cmp=self.cmp(node,tmp) 7 o' j6 r' n0 g& F3 ]/ n4 t& u F6 F if cmp<0:# }8 P4 ?" P" K
tmp=tmp.left 4 Q5 Q' k$ q1 V6 V0 ?" l else: : O5 B2 l5 ~$ i5 @; w! A) j) A' F/ ` if cmp>0: 2 e- V0 Z; x7 M5 x( Q tmp=tmp.right% ?8 z) O5 J, e
else:' O8 r2 e8 @, j; m/ d5 K7 ~
return tmp,parent 9 G0 D+ E8 B1 B4 f- o# K5 L i% s% b) e+ G4 B5 B- Q' d/ |
return None,parent " J* [% p. g! q" {) D6 @1 Y0 O# W9 V1 d( ^2 C* q
def rb_insert(self,data):6 ~0 o% N8 z0 D4 y
tmp=None) K% |8 A+ C) j1 x: U
node=Node(data)/ z( B3 J5 p% P2 J3 V
tmp,parent=self.rb_search_auxiliary(node) * ]( u) O& C3 L8 C& X: F 2 q9 X# R8 Y) y if tmp is not None: ( Q0 c" o6 J& c2 U! \. ^6 {" C; o return , i8 w4 G# Q1 H* t% q. ?* \& \6 a1 C+ n6 C
node.parent =parent3 N/ P( o' V: n l3 [/ a1 N3 ]
node.left=node.right=None% {. ]1 p( k) P! Y: j
node.color=RED; M% G7 J$ S- Q9 z! ?
6 a9 W0 k5 Q T; q, s( y( }
if parent is not None: ( b& x# j9 u! I- i4 C2 k . l5 T' W( d, o" S6 k- t if self.cmp(parent,node)>0:8 J5 V- k& i- A8 X5 L8 p1 L L
parent.left=node! [! D8 ^, d2 T: [
else: * p( H3 L K9 m; `3 D/ n; \ parent.right=node 0 e, p- _8 a( ~: ^ else:& A* _' V8 |+ L2 k$ I: N
self.root=node 0 ~+ ` D+ l& O4 v; a4 J return self.rb_insert_rebalance(node) ; D4 k; w7 S1 m" r & F1 S$ T# ?* \& ~ def rb_erase_rebalance(self,node,parent): - a- a; v9 r; B5 P2 O! Q3 L while((node is None or node.color==BLACK)and node !=self.root): 7 d' V. y% ]8 n, z; B" z if parent.left==node:% H5 a! T0 W' V" P& h0 \. X! J
other=parent.right ; T, M- V& T# n+ g, f3 w if other.color==RED:7 t9 ~5 I0 Z {, e
other.color=BALCK , o, p5 M, ] q" q M. l parent.color=RED - r8 p7 n& A" S' K self.rb_rotate_left(parent)$ r0 s) {6 F. _8 X
other=parent.right ) P9 X3 `' _0 u% O* N* |0 g- [ if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color ==BLACK):1 ?4 b7 |! ], Y* N1 o
other.color=RED2 |6 t; w: Q& k
node=parent : W. S* t1 A+ ]' J" j* Q4 `) R2 M2 u parent=node.parent3 F$ }' R" }% L& l3 w( D1 B) l
else:: s2 z! y- f, V; u- K
if other.right is None or other.right.color==BLACK:5 `' x4 |8 X: @' E4 U
" z, j; Z+ {, t; a# B& k# m0 C
if other.left is not None: & `5 u, a( L/ D8 r other.left.color=BLACK- b& a2 N n9 j; e# y
other.color=RED# G7 E: J' `! g1 u
self.rb_rotate_right(other) 2 T. x3 }, L: u. } other=parent.right7 Q4 b. B" c6 Q
: H/ m k- e w* V1 [
other.color=parent.color K" N8 c1 b( o- D* N$ ~7 L, a parent.color=BLACK6 F% X; r5 I" y' c$ F
if other.right is not None: 9 W3 i6 A. J# O5 h, h% J other.right.color=BLACK $ g6 D- ]4 H" }& X( h5 a self.rb_rotate_left(parent)) J% e ]" |9 V$ p3 J4 T
node=self.root 8 ^3 q+ `" n4 Z- h break 4 ~0 o0 Z' I* n1 K0 G+ N2 t" |& S5 { else: 5 J: C& O' u y8 A other=parent.left 6 Y1 q- S1 M8 _6 y% _) _- } if other.color==RED:% A1 k3 {9 t0 ^
other.color=BLACK; g; W/ g3 m7 p8 x! c ]. B
parent.color=RED$ [: |1 c C" z, T. B! o5 V7 M
self.rb_rotate_right(parent)- w$ k {% m% j F5 h/ }6 Z
other=parent.left6 c& e- Y) @0 w A4 F N3 R1 _
if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color==BLACK):) i; f" W- O4 m' ~
other.color=RED5 v+ g# ]# W) O0 q8 E
node=parent+ H/ s2 ?4 v& N% X. f4 M0 t
parent=node.parent ! Q& ]" _' {. V( K$ L/ c else:- j9 _2 q$ _0 O) | y
if other.left is None or other.left.color==BLACK:# \5 G) O7 D/ O! e6 H! F' x) m
if other.right is not None: ) O0 H$ I# A2 ^1 k G9 ]) l) Y other.right.color=BLACK 3 l. o1 W; k) K) C2 Z3 B R8 v& p. K8 E' i; p& o
other.color=RED4 B' P- i4 P; x1 M
self.rb_rotate_left(other)* ~2 {4 I, L% w4 s
other=parent.left 7 J) n7 [6 F) {# `4 W1 O! ~! i. M/ S/ J2 `% O, N9 `
other.color=parent.color3 q3 a( }4 V% E3 v4 u8 t# A
parent.color=BLACK ' z N* v$ u9 W) r3 o: r- S0 W1 ?9 _* ^" W- F$ I9 S6 W5 L
if other.left is not None: 7 x: u: O4 r1 s9 z' ^# y other.left.color=BLACK% }# I- E5 P& Z# |7 w
5 n% ~: l( S* L- Q% P3 p; v# _
self.rb_rotate_right(parent)6 z6 q/ _: C! S8 V& Y. u0 j& H: |- h* ~
node=self.root & b( j+ |/ ~" |) e8 p+ t5 Y break* {9 L9 O8 W* w' d3 k
* @$ y8 }7 C3 H+ L
1 C$ f% p+ g* s' D, h; |- @' {
4 k6 S$ s' T, A/ U2 d! O' b if node is not None: ) ^0 w6 N0 V6 C* |: w* R7 E: _, X node.color=BLACK " J) F% V y, D. K7 H1 V- a) q : ^: q* ~! A9 V: h# {8 b+ C9 {: d def rb_erase(self,data):$ x( s3 T0 O" o/ o7 d$ p) L. i0 ~
tmp_node=Node(data)- p& V- R5 V" m
node,parent = self.rb_search_auxiliary(tmp_node)4 D1 ]2 H4 d, z
if node is None:. H( q5 L( I# g( l
print "data is not exist." # }2 Y1 n" [ |) N! D2 N. B return7 X: P0 E$ k$ _. v4 S
+ @, v3 ^+ d4 ]: Z( D. R old =node . v& E, K7 Q, B$ S if node.left and node.right:) }! \$ n6 ~+ k* f% i+ [, ^4 K% ]; b4 O
node=node.right # B X3 [. B; e0 G8 I + S+ O# l# B1 I% O& x% O left=node.left 2 E6 q. M" A, u while left is not None:" H+ Q$ _0 j5 e" B3 K
node =left & f: ^ w' ?% X; O4 v3 ?' [ left=node.left* s0 V! @8 D, S# [9 Q+ A
/ X9 _# Y7 B# i) `% q
child=node.right3 H7 ^# r8 x" x% b
parent=node.parent6 k0 D9 L/ I( \# `( T8 ?
color=node.color $ T9 \4 r. f5 r . |0 B0 L. t+ R+ X: G6 s if child: 0 q+ P3 X% p0 ]6 | child.parent=parent* G/ s7 [; |) A2 \+ M7 D
if parent: * r/ F( O7 [* j$ G7 N5 c( ^ ] if parent.left==node: ' P( C, _2 b5 R% q) K parent.left=child) S" V1 S$ A: P H# C& g0 n$ @
else: : ]7 g: [0 ?1 y1 M' p' m# f6 }# H parent.right=child' l$ T' Y/ b/ m8 s. b& ^. `
6 J0 z4 ]6 R1 Z% g2 F7 u( w; r: l+ Q
else: % g2 L; h& J' r* j self.root=child1 R4 T9 @/ L; y7 x
- Y! z- b% C& `9 J2 W1 x' j if node.parent==old:! t: m- D* V, G5 g" h- m
parent=node( h( L% K- J s% G' @0 v6 @
node.parent=old.parent# ?1 W8 q9 o5 k. E3 A& Q
node.color=old.color: O G! L0 a) w& [1 O/ G
node.right=old.right4 D3 A- Z2 [$ V6 [; B& [0 R3 g! l
node.left=old.left g# Y6 v5 u9 v* [ y- K, k* O4 e3 S
7 e; ]$ Q) W/ @* A$ V! N) g+ g' u4 u
if old.parent: - U/ m8 C9 F( y8 z b8 i- w if old.parent.left==old: - Z* a+ h _: e. l1 ` c old.parent.left=node* g+ G- b# J$ ]5 f
else: : l7 U8 j/ f) R7 T old.parent.right=node1 d8 D2 u0 O/ `$ T f, E
else:: N4 s4 N& V! B+ m3 }2 E7 b8 m( L
self.root=node V- [5 n# f2 L+ ^4 j! p+ G- c& A, L) I% k6 \
old.left.parent=node# z1 a* h) Z6 ^1 a2 v! P' T; U* v
if old.right:& Z2 `/ B1 X ]- j' p
old.right.parent=node& s2 t" ~% m2 t- V; g! m
# A. t u! ^) j" }. z2 t3 b+ ~
else: - Q' }7 L+ t# e if node.left is None:. v- _. l" F3 ^; o7 O+ e& {& C
child =node.right- y: U' A2 z* _5 I6 U' X* t: X# O. u1 c
else:6 |. k6 a9 z" j6 `( x f5 a n
if node.left is not None:/ ]7 D8 M$ L( t$ i) c+ V$ p
child=node.left ! u) x$ ?5 F4 J: N2 M; U else:+ u1 F* m& D# l& |. Y- n) o
child=None & e p+ ^+ {2 i, K parent=node.parent* Q; T- y* M, l1 F7 a( j& U
color=node.color0 S4 K2 f# s( e: V2 y! `/ X
if child:; Q2 V- H! b% n
child.parent=parent, _0 A' t& E8 Z4 @2 g, }
if parent:4 Y1 G4 |: ~4 k; k8 U
if parent.left==node:( r3 ^/ `' A3 k! X5 o# i0 D
parent.left=child: T$ p( \% _) t" c9 C$ P5 h
else:* _. J6 x& J8 ^0 h N6 c# t
parent.right=child( H% g& a: p: }- H% U: m
else:5 T3 I( U- W5 x$ M
self.root=child& J, d# m6 p3 a! i! C) k& W
* S! W: Y- _+ \' O6 w" {/ r
if color==BLACK: ' n* I- z" P) J1 y) I, h ) t4 W7 o' f8 Y) ] F1 Z self.rb_erase_rebalance(child,parent)% ]) ^; j& N- G% u0 b0 g* v8 O
( r) n% g8 @' E1 S/ Y) H' N w
1 U9 e5 D" H# ]3 j/ Y% h8 V, Q
def rb_travelse(self,node):& u0 k" O, h- V
if node is not None: 8 ^/ `; A; }: C8 ^) E) y print str(node.data)+'\t'+str(node.color)' @& F8 X: J! R4 V" `/ Z% s7 g
self.rb_travelse(node.left) 7 c, m3 g4 c- {% U0 ?" k if node.parent: $ L3 K" ^( P7 |: q if node.parent.color==0 and node.color==0: 2 y% W! `6 c" V9 [6 E& Z print "error"+ ^+ z( x. ]9 c2 A* F
return1 h9 Z' W' i& j0 p% k
self.rb_travelse(node.right) : P$ w$ L, C3 o3 P if node.parent:$ v) i- d- r0 M" t% x
if node.parent.color==0 and node.color==0:7 y7 N0 I V: g7 V
print "error" * ]- C$ r" J z return) F6 b4 i: a" w) O$ E
* ^) l0 i2 A6 t" I3 F0 J3 v
return & M% v9 Z3 K: c$ V0 ` : p; a8 W& v! d& ?) A# o8 C 1 y& [9 R* y4 }% p* W6 u( V3 L0 e def cmp(self,node1,node2):" b a: b( c4 D/ c" V7 O
if node1.data>node2.data : $ e' N$ V8 C' L4 |2 P7 U6 c return 1* Q' q& ~* R/ x7 O
if node1.data==node2.data : 5 H1 w0 E7 Z! B3 f return 0 6 t/ b3 Z- X" P! u/ ^ if node1.data<node2.data:. |3 t2 K4 q4 ^6 x, m9 R, z
return -1 , b$ |; x2 ~& K+ O1 X" C4 S% k$ n& P
if __name__=="__main__": * u; J, ^$ F0 M7 I* q5 p6 ? print "main" ) J1 Z6 B. j _0 c2 w data=[28,6,39,78,6,43,61,56,71,38]+ N+ z$ Y/ q1 l3 i6 Z! d: P
#for i in range(10): 7 f! \3 ~; {7 j9 T. P. U/ \5 W# L! k7 p # rand_num = random.randint(0, 100), q! x" {1 R7 O
# data.append(rand_num)$ ^, W8 b2 U1 w* b* [% A, C w
#print data 4 C( ]' p8 i Z+ O* R t=RBtree() 7 J6 C/ _, d ~. _* R p2 G 8 i2 [; @7 _2 j' J2 O 0 R0 q. }- D0 i, }8 K for i in range(10): 7 l' j6 E3 U% C t.rb_insert(data[i])$ ?+ P0 s- d' t
3 `, C3 Y& t9 z5 F6 p/ X# e' {* }
. ]: O7 U! p1 q. p t.rb_travelse(t.root). U' D6 X W, j. B2 C0 F
( c- j9 r/ ?* j1 i: A) v+ o) d print "---------------------------------"3 E2 `, R$ F. w
t.rb_erase(data[7]) 0 L$ U T2 [% Q3 N' \ & ?# o6 g- C, [7 E" q: V b
t.rb_travelse(t.root) " c2 B6 Y; h7 A% q$ F# V/ ~. C3 w' M' [5 K