$ ]$ W. _# Q, ]' ` Pimport os" N1 C4 F3 \6 n& G/ ]6 }
import random / W" i0 @" H2 N1 L0 g ; o9 X2 X7 a# g/ |; qRED = 0' E; u" z; F( W0 w0 i
BLACK = 18 f7 e) w/ a7 z, p# S6 ~
4 O/ n; }. b: E% a$ t7 t6 K+ nclass Vector(object): " ]5 y, K: _8 e; @( \ def __init__(self,x=None,y=None):0 {. O. ?% j. \& A: [4 k
self.x=x / Q5 N( g; q& a3 l1 H self.y=y 2 ]" y% j, h3 c$ M0 |2 C4 k , N L. z+ b+ l/ ?class Node(object):5 X: x9 Z$ A/ V1 C0 |
"""docstring for Node"""* X8 u: S% K. y" W$ y, t* E
def __init__(self,data=None,color=RED,left=None,right=None,parent=None): " d- `9 q" J( N- \* j self.data = data " c# o7 f9 o9 v, }/ {/ ~ self.color = color* _' P/ Y4 ~1 @5 z
self.left = left/ R9 L9 X, f" j7 b: _2 S% ^
self.right = right 1 F& S% R0 a# I! u' c2 | self.parent = parent- k# I* R/ ~+ A$ u8 i) g. V; E. |% X
- A1 M f. H& S6 hclass RBtree(object): 9 `/ |2 y$ r4 N- U3 t8 c. K0 s9 c def __init__(self): : L: x* _+ ?, E' x self.root=None2 n' b5 [( l# r- A) W3 Y* l
self.size=0 / D6 `8 o+ S7 o i9 Q5 j6 O( p + ]# d" t2 g E. S6 Z0 I% g% S def rb_rotate_left(self,node): + R) S* I q% a% N- Q right=node.right5 U6 s4 N9 P6 f0 i2 [, ]
- f5 L) K( W# u% E+ k2 ]$ Q
node.right=right.left 6 g6 A; o: @5 @, a7 J1 H X6 |& E! c if node.right is not None: 3 s% m, C; r, d s0 L1 n+ _ right.left.parent=node 0 g8 P* B3 {! ]8 n& E6 S; K. @7 X* [& F* Z
right.left=node 9 A1 a. Z. d- r8 \( i1 K* H right.parent=node.parent # m0 N( A8 C; ]7 n& x' ]; j3 ?3 n Z. e& z' P0 J
if right.parent is None:3 u; R3 Y$ O+ [, o6 e. _
% l: D7 i8 R( v' b$ [
self.root=right 7 O1 K" A. U- J1 g; \) B else:+ L/ A p" j$ Q& Q
if node==node.parent.right: 2 C& A5 N& V) G5 C node.parent.right=right0 g4 ?) @& j0 |
else: - R6 b$ W6 f9 l) y node.parent.left=right 2 Y b# r. z7 O4 A8 N; N node.parent =right, B6 Q. Y3 }. m9 M9 b
, `: K) W7 s2 k7 w- f3 ~( X ]1 P8 G2 B w
def rb_rotate_right(self,node): % }0 e- `7 d$ |# v: \4 M$ P left=node.left% f. x2 t0 A9 j( Z: m
node.left=left.right, z4 M" j% l8 \- R O! Q
8 `/ l# l" w( |6 D& ?- @1 [
if node.left is not None: + I7 Z/ ?4 r) r2 q left.right.parent=node( Z8 I+ t" j/ u( j* [* v$ Z% O2 K
) g1 k) t& E: u5 Z/ g4 k: T6 e
left.right=node2 i# }& W! J7 }# h5 a
left.parent=node.parent 2 \3 |+ i$ H+ f2 u9 C. j - Q2 M7 N" Z& ~4 \ m1 l if left.parent is None: 0 h& T" B) M4 Q+ s self.root=left % G8 B/ v: Q+ y6 Z. E else: 7 R; G: _- H' H+ i- p if node==node.parent.right: ) K9 a3 u X4 |/ G+ i node.parent.right=left; a- A/ |. ?. K1 x
else: 6 o& d6 d7 G" f- D node.parent.left=left2 J( j, [; s# ^6 y3 s3 G/ x" [
node.parent=left5 K. [5 E( n- R5 v$ n7 j" b( u N
5 P7 | C, K# u: O def rb_insert_rebalance(self,node): % x8 d1 M7 ]$ h% y* A parent=node.parent / h9 u1 v \0 c. c) T while parent and parent.color==RED: : w2 B7 u0 R, K7 h6 w- I8 V' d! I- z3 w9 E gparent = parent.parent j1 e& j( d3 n# ^
if parent==gparent.left: % W- g; s* o# c9 ?' c. } uncle=gparent.right 4 Z; u: @& A5 v9 v5 U) S if uncle and uncle.color==RED: 5 o) A7 ~ p1 b- l( r5 V2 J uncle.color=BLACK 5 h. X; _; y6 @" z5 L parent.color=BLACK( c: I( v1 b7 T7 x5 O4 y: K
gparent.color=RED 2 u: z$ }* z8 A+ a, }0 z& B) h node=gparent ' G5 n( k, [+ V, d else:2 h7 d9 q% n/ }& U
if parent.right==node:5 M" [3 H5 w5 i1 P9 k
self.rb_rotate_left(parent) 1 @/ g9 D0 M; R8 s6 \ tmp=parent+ }/ z+ ?1 y0 |2 M8 j( e; l( ^
parent=node ) `6 K$ f8 u5 A' u( N) ]8 Q- Z node=tmp ( L( R0 B; Y. u parent.color=BLACK( n) d5 v' H, _
gparent.color=RED I7 e' r ?' ^' {; G" X# ^9 H
. u8 Y: u! Q: ~4 j$ p) M# _ self.rb_rotate_right(gparent) " i' u9 [, I" J5 d2 z: I2 T9 l 4 F0 o* M6 w4 E+ |, f if uncle: 6 V2 e3 R- }' M/ P if uncle.right: ! [6 B0 H5 E9 ^( E5 v- G9 U2 I9 D node=uncle.right $ f+ e. L" O& W+ l8 M else:9 V! P; u( i+ X/ q% g
uncle=gparent.left # ]0 b! s7 t( c5 b. q if uncle and uncle.color==RED: |' y& _# Y* r, h, f
uncle.color=BLACK # ~% L, G- j% z2 e: x3 m0 K parent.color=BLACK- u5 G( W3 k& o- T# i( G4 b
gparent.color=RED ) D4 W/ f* ~$ T9 \# q node=gparent6 H& J% F9 }1 ?' v3 O8 z0 a* Q
else: 0 h, f" ^4 r9 q2 ? if parent.left==node: 5 l/ } V1 A) F; d3 u self.rb_rotate_right(parent) ' m( `8 ]* ~: R4 _- g tmp=parent3 j( U( g; v6 M0 o
parent=node* ~6 K& x3 k: ]1 }
node=tmp: {9 m& H9 J$ Y8 E W9 v& |& R
parent.color=BLACK 9 _' [; J. H: k$ f gparent.color=RED4 k1 t, N: _4 r! ` r( a7 b c
self.rb_rotate_left(gparent)/ S0 t9 @% e4 A2 _
& P" Q2 l/ x8 j! e/ b/ O
if uncle: ; [+ p* U+ K4 N0 D1 w% x: x! G: q if uncle.left: ! }1 z- C- o1 _( \! P* e node=uncle.left ) r$ R( b. K# t* D v% A parent=node.parent* Q% q! w6 s4 A3 }
# s1 d. f& z# U* A: F/ k r
J1 S* c0 k4 _# K self.root.color=BLACK 7 ], }! h$ d: Z ' C- J; L" M! s
- K& Y4 N' c; c/ ?2 o) h def rb_search_auxiliary(self,node): ( U' T; B( v) b+ \# D tmp=self.root , ?% Q) F$ ]0 R& i$ ]8 l( v5 z parent=None$ Q) f6 t; m! J: m) V5 T4 ~9 a
while tmp is not None: & i* B! s/ G! c6 H p# ] parent=tmp# {" ]" \: x. @5 _/ t
cmp=self.cmp(node,tmp)7 c1 S* o) f% ^- f0 i; i, l
if cmp<0:/ A4 L) c4 Y- Y
tmp=tmp.left% n, h# ?* L' t7 B5 S+ |* s
else: 2 [" H2 M6 Q# S9 X w: [ if cmp>0: ) l- C; j$ L: M4 Y w! q tmp=tmp.right1 d1 l9 o" S6 f$ b6 E! b) B" B* A
else:: Z7 d& `0 |# c# b8 C$ c. H
return tmp,parent6 y3 j# l% n% N6 N' [ h
% J% ~3 T4 A4 \7 F
return None,parent5 n# a4 d: |; ~- B. r8 c4 @) `; e
$ z# U, e/ [9 J
def rb_insert(self,data):, W6 u! `2 o9 ^; t, Y
tmp=None 2 r, Q9 F- n* }! R3 m5 o: | node=Node(data), i! h7 Z; ?- O
tmp,parent=self.rb_search_auxiliary(node)( n3 B+ x( B y& J& _3 o
# t0 g( x9 h" X. x A% J0 `
if tmp is not None:9 z: C [/ d) h5 Z6 \
return + O! Z. ]% V1 z7 n1 U; T/ U/ m : D& E! D( W( R+ m p' a+ r/ Z node.parent =parent ( R! M; c$ `! }3 h5 r* ~2 t$ }0 h node.left=node.right=None$ S G% T3 E/ [; y* `( ], Z
node.color=RED( q" z6 Q/ o# Z! D+ I/ n
0 |" ?$ p) Y, r7 g' M" V
if parent is not None:7 R: ?) O4 @, T% o- w
* `, M7 {( N; Q5 b6 k; }
if self.cmp(parent,node)>0: + ?: g5 O9 [% ?6 F, C/ e A parent.left=node0 g; M) S7 J. e9 q) l% x# t4 B
else: * V( j# ~( x; \6 |+ D) Z; v# j( t parent.right=node7 {$ e' ? T7 j3 l/ g9 M
else: 0 m/ Y7 H. { `# k* `2 \6 U self.root=node1 D4 M* J4 _, y; c/ D
return self.rb_insert_rebalance(node) 6 g$ Q+ z, M1 S8 b: H/ O7 F2 r; J4 o9 D8 C0 S: G* u
def rb_erase_rebalance(self,node,parent):; c! H1 x6 j: Y6 k. o# l% J7 S) X
while((node is None or node.color==BLACK)and node !=self.root):2 t5 F" X( _# j, p
if parent.left==node:; }1 n% R3 K; \0 k
other=parent.right9 [- E1 b- d- Y& l
if other.color==RED: ( Z8 }" l1 P( ^: j5 N other.color=BALCK0 k; ^& _2 |' }
parent.color=RED + k1 i6 H+ `! z$ b self.rb_rotate_left(parent) _" t. X3 g1 M w4 T* B6 I! T, H& q
other=parent.right 2 m4 I: N2 `; k9 D1 X* j8 n if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color ==BLACK): 1 {2 d. m' r# x2 K: F. e0 P& p other.color=RED ) u) `7 T+ I! c3 n* B+ s node=parent8 o! z. d" [: y, C
parent=node.parent ) m0 r3 S/ P( y6 O else: s* Z" n4 v+ i if other.right is None or other.right.color==BLACK:6 b* x b, |- _
* B2 f6 R) e7 P; j3 n( ]
if other.left is not None: . F/ c6 o2 R" G- }- K other.left.color=BLACK " O9 P" J; X L) k+ z- _& T other.color=RED 1 o( w: o" @" I4 Y6 D self.rb_rotate_right(other)+ Z& B9 ]$ S6 U. Q. |7 R' u
other=parent.right 5 _% v7 C0 ~- s! C$ g : U* E& K, a3 ]; L4 t other.color=parent.color 3 Q0 V8 L' ~2 y* D$ `& G parent.color=BLACK" Q; Y/ P, L3 G$ s+ \+ Z( U3 A- M2 q
if other.right is not None:; b0 o, l' e5 b* V( A+ Q( L
other.right.color=BLACK6 k6 g7 [7 u4 x! H
self.rb_rotate_left(parent): m& F5 Q7 I$ U4 o$ q7 G) u6 o# f
node=self.root 5 J/ ]/ B8 }% r1 w break) w( i6 q8 f8 ~ v g
else:4 |& K2 s: m3 F- N% [
other=parent.left4 \, ^) h" j: V4 o: B
if other.color==RED: * e& N+ O+ y5 w5 A) Q _# D other.color=BLACK 0 _, X, ~) p1 S2 p parent.color=RED1 V% \& D) |3 E `# `5 I
self.rb_rotate_right(parent)+ `# C/ }! B( V" ~
other=parent.left l- w! ^% b; x* ?7 t7 {7 [ if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color==BLACK):; a. @% \. J) H- I2 Y* f
other.color=RED, _- U$ |3 {- U2 j
node=parent ; L* Q4 Y+ A4 C8 X3 a1 g( x parent=node.parent' w5 r' h! @# l0 d: _
else: 9 K7 k9 B. @# A, X7 r: F' d if other.left is None or other.left.color==BLACK:( A0 \) u* ^# V: P4 s
if other.right is not None: * n* e1 `, D' F1 t6 a2 T# M other.right.color=BLACK7 x( Z+ o4 T, f6 Y" n6 c! L
) Q& e, q& N& L/ S( K6 E; }
other.color=RED0 C+ S0 L; l( d
self.rb_rotate_left(other) $ f. y' ]6 J( s, J# g" N7 z$ ] other=parent.left . X7 f8 m5 ]2 Q$ g8 K4 B/ p1 `5 E' c; l+ C; A9 Y( t
other.color=parent.color 4 i' ]& N% J* |6 T parent.color=BLACK " b% `0 C. u# W ( B/ p+ q* {3 R8 r1 O. Z! j if other.left is not None: Q: L7 h' h) w/ u5 I5 T
other.left.color=BLACK: C# a9 t: Y( |- ^8 |7 w, J
6 h) v4 w, y' B( Q, b8 v- F
self.rb_rotate_right(parent) ( j2 V( K; X8 n8 K3 F) F node=self.root4 e+ C3 z/ h ]7 |/ ]
break ( D5 D. g) n! r9 T) p9 D4 ]$ w 3 n4 E. d) x* t3 c7 C& ?( v' j, I5 b# n; v% _* h; O& v" ~( o
+ S7 u: w7 }7 p0 b( f
if node is not None:, ` B$ W; @& s" I I( f1 I5 L" D5 B
node.color=BLACK - ?1 G# W) ^2 x9 H6 k
- c8 u2 o! m& m8 ?4 J( {9 B
def rb_erase(self,data):4 _, W1 o% W$ |' o) R, F3 e
tmp_node=Node(data) - h: {& f Y) s! P5 X& U node,parent = self.rb_search_auxiliary(tmp_node) 5 x+ c3 U# O6 [ {9 H if node is None:7 D7 v4 ~$ o4 O# c4 E- m
print "data is not exist."* L& B: ~7 d; c
return # m Q$ C. f& g! J0 p* I/ m/ I" h ! d2 l) K) _7 M# O$ E1 L& z: [
old =node 0 a' g; l5 J0 s' n if node.left and node.right: , ~7 _1 A) b" }% D! {' [9 T" D node=node.right # N* R7 B( B3 _+ @7 w7 ^ ! q& {; Q. c- E% B3 }+ W+ v! |5 d left=node.left m6 F9 j& p: |7 F8 g# a
while left is not None:# q; a. E) u; E6 N0 d" |/ K
node =left4 }9 Z& }; I$ B3 H2 w, I4 ^, D3 U q
left=node.left " ^; y/ F5 _% P v. Q/ L1 ^: h0 C% T# p! @- o" r
child=node.right ! m7 C% p' p* T$ Z parent=node.parent2 R3 e" \# M7 B
color=node.color 1 b( z: [! D* L# @8 l2 K' U S) S3 O- ^$ j! x
if child:0 _3 C# x2 \" }* r) J( |
child.parent=parent6 b, t( v" C- ?1 W* `; {& L
if parent:' W7 C' `+ j/ ]) M6 @/ `( ]( y
if parent.left==node: ' i/ w; e) y: j1 z9 j parent.left=child - X8 Y) `2 F) J. p( b1 A$ \4 @5 J else: 2 `8 B8 i0 @3 p2 j, N: |) M parent.right=child8 ?& L% T" h/ c) R5 t4 y) ^$ u) z
7 C6 L9 Z. y1 _* V: }
else:+ z" _/ ?( b8 j4 G9 F3 D0 d- W
self.root=child2 [- W' p- H' h$ Z0 r, E
7 c5 i! s9 R+ k/ @* X; ` if node.parent==old: v5 \: T( q/ x parent=node 6 ]/ T5 T6 V5 T- r) B- b; ~' G7 g node.parent=old.parent4 S& H* X% R2 m
node.color=old.color 1 c8 [1 b2 p3 B( H' o node.right=old.right / F# F& [ \: d3 _& W node.left=old.left6 |4 Y# |6 c4 @+ ~* r7 n% L* i s m2 g
* f/ |& `) ?, f z if old.parent: / W; C% a9 n7 F9 m, N7 ^( t5 N if old.parent.left==old: # ?7 G7 U# H. D* t old.parent.left=node 9 Z3 T+ J" i' ]5 z! i5 a0 j$ _ else: ) e' f: H# h0 N/ i; k9 L old.parent.right=node 7 |4 f1 E( `7 b+ q. T, _ else: " y7 m9 {; q, x/ V6 o/ L" X+ i2 ~ self.root=node/ O5 F8 W( Q0 V. l2 v y
* `0 U ]# A8 V4 W
old.left.parent=node; h. g5 Y7 }) @# T# i
if old.right: + [& J! Z' n1 {$ u! H X0 x" N old.right.parent=node ) A: s) F9 r; B% V% e" G& w# b; s4 t3 a
else:/ a1 `5 E7 K+ r$ U- s
if node.left is None:+ Q* n# G8 k6 [
child =node.right % Y0 ]* A& i2 N, K u else: ; m' ]% ^/ Q5 Y. l: w" F7 D4 b if node.left is not None: ! _. ~4 r1 q! i4 ?' ~- t- l5 a child=node.left2 v8 |/ L Q, G5 H/ j1 A. B
else: , j0 q" d4 c( I; {+ h" X( I" @ child=None 0 q# F, y- { w* s. o1 x parent=node.parent4 R9 z6 ~. d$ ^ O
color=node.color 1 K; b( ^6 e* F- i: m8 v/ p9 F if child:9 w. S' W: L. G8 h
child.parent=parent3 t5 a+ u4 i1 R& o5 N( C, d
if parent:( J2 W3 n% Y6 n
if parent.left==node: , G( n0 M( z2 j$ c& Y, x d# H parent.left=child7 ?( M( f8 j/ y& C* S
else: & d$ @( S& m- |# Z parent.right=child" n. f, D4 y& F# J. {# N
else:5 h( W3 H3 g( Q l- N# w8 ] M
self.root=child. F5 f4 f4 Q5 ^+ K7 z$ X
+ V( |6 S! Q: E/ s6 k: R0 G9 @
if color==BLACK:6 q% d4 U6 L9 o$ x
7 Q" q/ @! E" _
self.rb_erase_rebalance(child,parent)7 }7 C$ b7 m) u& ^
6 N3 K, A& d9 r o+ r( _. I, x 9 j& x# [6 v/ }/ P, } def rb_travelse(self,node):6 P* q* ]; e; t2 x) s
if node is not None: ) z- r/ K; c* w& O print str(node.data)+'\t'+str(node.color)% W( z m2 @. A: D( O
self.rb_travelse(node.left) ! D; m7 O9 q X& r if node.parent:7 v9 _" i7 ~* l% E# W
if node.parent.color==0 and node.color==0: ) F7 S8 k' ?. H5 T print "error"! F# | k2 E) r1 M7 c7 r( k
return0 X- b' A9 V5 Y# y
self.rb_travelse(node.right)! l- t3 W: i0 G8 x1 A
if node.parent:# [4 a; d# q5 _8 {) x
if node.parent.color==0 and node.color==0:& a" ?; B4 O- |# W
print "error"( T( g H1 Y! b
return1 K: Z; q$ d! Y+ A
. e2 g$ F4 W0 m return 1 Z1 }& ?! p+ V7 E* q! ~ - R. C; |# d% K1 X8 X( f9 x3 x
8 F' ~3 N, F/ ~ def cmp(self,node1,node2):8 l" H; Z4 `6 K7 Y! ]9 L
if node1.data>node2.data :5 Z$ g# L4 s6 S- K) U
return 1 $ B$ v+ w2 d5 V% c9 }! b) k# h if node1.data==node2.data : % s- b( M' X: o U% d; ~7 N& E return 02 g9 C( u Y; O
if node1.data<node2.data: . i1 ~/ q) R, X, s$ ? return -1 ; d7 V/ o6 r/ h* @* B$ B4 r ( S8 J, x6 H6 ]if __name__=="__main__": % F1 F; y# s( t8 C1 C6 ^/ d print "main" $ T6 _7 }7 @/ v6 d+ [/ U# @: J4 n4 j data=[28,6,39,78,6,43,61,56,71,38], `# y7 g' N/ G; o1 ~+ D9 {
#for i in range(10): # ~/ P) e0 [/ V- w # rand_num = random.randint(0, 100) - B2 T$ y8 Y4 K # data.append(rand_num)" Z. i3 i& ] I/ ^; B& g6 N
#print data 3 b- y, w0 n# q$ p5 B) w t=RBtree()- D1 J" m* e+ t) z2 j8 j. P% V
" {) o: C" k- @9 |4 y0 w# N; h 2 d& v% I$ ?0 _. `& W& O for i in range(10):; s" f) m7 C, v
t.rb_insert(data[i])6 A! F- v) n8 b9 L9 y/ R( D& E
8 `) ?: x U1 a4 e6 V! t4 C
# N% ]. r1 C6 E; j7 C* V
t.rb_travelse(t.root)$ \4 |. M0 `* B) V5 @/ C# S
! Y: y: ^+ U$ R4 b: t/ b print "---------------------------------" - r6 q' b9 r3 k8 T [' u3 t t.rb_erase(data[7]) C7 v0 K/ H* }. g& X 5 @+ `& {, z7 S9 \/ f t.rb_travelse(t.root) , S( u8 q: X- f% n 2 y7 t Q# b8 E0 b2 R. V& Z' m