3 E1 l8 r* k& Y& Wclass Vector(object):- o, D) W) t/ L
def __init__(self,x=None,y=None):0 j9 Z0 E$ ~' u+ z
self.x=x# j' P4 l: ^- H7 t* W1 z- U: i
self.y=y 3 O: U" c3 j* x3 o$ a; i |# w% Y4 \$ Y3 C! P5 }+ `
class Node(object):8 L! ?' ?* |" u5 J/ f
"""docstring for Node"""$ I* Y$ a- y0 E1 _# X4 Y
def __init__(self,data=None,color=RED,left=None,right=None,parent=None):5 f' o/ R' ?2 M8 E) Y; r7 z
self.data = data 1 r$ w% K4 Q" Q self.color = color6 b9 ]( M: r1 {( S; M# o" W. u7 f! C
self.left = left ; E5 d; n/ C+ J self.right = right ' i( i/ k g% `& @ self.parent = parent: ~3 e6 v) I" B8 e/ m
% f4 T% W0 j8 A% W3 X
class RBtree(object): ! h( Y7 r2 W' A# |$ G( l def __init__(self):( o* h! }! B0 I; j S
self.root=None' }" g" i- _% H9 F" `7 r7 H% x; n
self.size=0; |1 Z/ Y# `" p( Q& w% }- l
1 H: H& K, B# a& m/ z/ T
def rb_rotate_left(self,node): I- C6 L& U6 @4 X( F) N
right=node.right! }5 S2 a5 d/ g8 H, A B
" T$ q8 q; G) [: R y4 V2 s node.right=right.left7 [3 S; i* s) h, ?- H. t& I
if node.right is not None:) A$ p G2 _& n/ b" X8 _" g
right.left.parent=node' f( t7 x" |8 }
: O4 t% Q% V7 h) @4 ]: @; F4 ^; X
right.left=node + m3 Z% G6 v# ?, v" W3 B, G4 _" c' F9 S right.parent=node.parent* C ?8 W- o$ A
$ T" R/ w; L$ c3 o7 V( D if right.parent is None:. E5 X7 d/ w9 F1 D, n: \( O
+ J! x3 V3 M# x+ u/ m) V% K
self.root=right : u# X0 C! x/ F3 s else: 7 M, I3 p& J7 O% @- d9 } B if node==node.parent.right: - q$ P$ n# H& e' N) j' u node.parent.right=right) h- O" j$ {0 p N) l+ y H
else:0 @ r7 g) R6 H4 s; X! y" j
node.parent.left=right ! h+ V7 q- d/ V# C, M3 F% D node.parent =right7 E6 X) G7 b3 S3 ^: {" }/ O
* W9 N! `# r; \+ g2 U# l+ ^0 K( K. \: C) |, d4 ]6 v) ^4 a
def rb_rotate_right(self,node): 5 [1 r* }, { m' ~5 t! A left=node.left, }1 O/ s7 z+ j5 f+ h: @
node.left=left.right/ W+ V, y* I% v2 B( E4 Y
+ ~. f) ^4 c3 k
if node.left is not None:: @" J! i1 w B' E d' }
left.right.parent=node8 [( j; v8 ?% X+ v6 ^
$ r4 v7 P- a* q5 q( u left.right=node8 o0 X) _2 z* R" |0 D$ i* Y
left.parent=node.parent 4 h5 w7 X* d0 a7 B- k' ?6 I ; p5 Q$ j, l+ } if left.parent is None:& y- s }& j. i
self.root=left 1 a) r: E# [) F h: K' k9 H; y) t else:, N0 T( S* A. d1 k a% j6 G6 M) f
if node==node.parent.right:" K. o5 X, c! D
node.parent.right=left1 o, x" N" H# R) K+ [
else:* {* ~' T- o. X# E7 e6 v
node.parent.left=left( s: x! t' C% d" D# ?6 c
node.parent=left* v! W/ p0 t1 U/ j0 X7 s# r
0 r6 C: [6 W c def rb_insert_rebalance(self,node): 7 W2 o1 P4 P, [2 d2 I w' o parent=node.parent E; B8 E8 d# j5 L while parent and parent.color==RED: , f; k. y. b, } gparent = parent.parent+ G3 ?0 b! `0 T( r" p% \# M
if parent==gparent.left:( l3 |" P1 t3 ?( V }. C9 O' t# {
uncle=gparent.right ( h3 G) I' i! u" `0 W4 E% W% M if uncle and uncle.color==RED:/ Q( O8 e" U% W6 y
uncle.color=BLACK # s- E& R- e6 P( V5 _ parent.color=BLACK . f; |8 U9 h$ ] gparent.color=RED4 `! K4 ^9 ?! ]6 }/ h
node=gparent ( _) h$ v- I: v0 e else: 1 ~* ~ f* Y7 u7 s* P; G if parent.right==node: 3 m4 S. h2 `$ g" U/ R- K* w7 [- W self.rb_rotate_left(parent) ' R& f1 ]1 A9 K$ d tmp=parent8 T# B; w0 X$ K' F8 M# S
parent=node 8 P! G! d& m% | node=tmp2 |9 C; {! B) U3 i
parent.color=BLACK * Z: j/ I8 f! z1 J2 N; \0 ~- F9 v gparent.color=RED 2 H$ n0 T* w1 j2 E+ }% \' ?# A# E5 A- O+ I+ B9 O
self.rb_rotate_right(gparent) 0 J2 S% F0 ?% G0 D) o- } 0 \- Y: B* _$ \. C7 T if uncle: 6 \- Z# {6 Q. M& } if uncle.right:* Z3 M5 q6 M/ P7 j: M
node=uncle.right ' [ t* e% U; _5 I else:) o% o& [3 X+ S( G) K# p: U/ p* B
uncle=gparent.left$ p; `# \+ k. _9 t1 V
if uncle and uncle.color==RED: 1 l" s; K) c; x uncle.color=BLACK 2 n( F% | q* x parent.color=BLACK % C8 U9 q/ m! I$ b% z1 t+ h gparent.color=RED % o" M- w* }$ G: O node=gparent : Y. r! S" [& `' a$ ?6 h: q. o else: 3 l) B( J+ r) @3 C! t9 ~8 U if parent.left==node: " _1 w) F, z4 d! b self.rb_rotate_right(parent) # H& s" {3 Z: Y; E, N' ]; E tmp=parent 7 W# \1 q3 a) w2 V4 {- _" S parent=node' @2 J) b4 o+ u1 k+ p
node=tmp- S6 h# M K( V
parent.color=BLACK1 S7 E3 F! H5 d' C6 F2 [
gparent.color=RED * v& W( P* v/ C3 ]' Z self.rb_rotate_left(gparent)8 D! ?+ K. | j' e3 ]' [0 s
* m2 R9 d) _* n Z& k, F if uncle: 5 f3 Q0 r/ @. m0 t* l4 Y: M6 [: T if uncle.left: " o) y9 J( E* ?! Q- X: F node=uncle.left# F. E6 `& X5 l7 e" i. F$ r- g( V
parent=node.parent . d4 f1 I# X8 J2 g. @& O- f) k: o
& ?. }, F1 L4 u" X5 E self.root.color=BLACK 9 Q1 ?7 k. z( m H" P x# b 7 j- w s$ I/ ^
* V8 r( ~' C- y! G# K
def rb_search_auxiliary(self,node): ( s2 G+ l4 D9 N) y& g- {7 m tmp=self.root ' l: h* g2 V' P) r parent=None . P8 Y) A$ j4 k6 K. I while tmp is not None: ; }! u- {8 A/ m0 o- Y8 A1 g parent=tmp 5 a" G; y) Q4 p) {2 b$ x) T" n# B cmp=self.cmp(node,tmp) - D+ k; e j$ P% \ if cmp<0:- z$ b4 ?7 ~( ~
tmp=tmp.left! \& S7 a# @* C1 ]% N5 B2 C+ G
else:1 M1 J4 _2 v/ f$ a4 T! q
if cmp>0:% @3 V; `5 [3 f5 J
tmp=tmp.right% t7 W) ~( ]7 V
else:% I8 V4 I- Y7 Y: w/ y
return tmp,parent6 t. R: Z* g' K( S. p
6 }( l% ]$ Y u+ e }: K, _ return None,parent 7 U [' o7 S/ I& y2 B$ d; v # o) }/ A8 n( K& `* T def rb_insert(self,data): ) i$ F9 d- W3 ?1 r$ A2 H tmp=None) b P9 }2 x5 Q' @6 K( T# _- ~
node=Node(data)% g2 p# @) f: n s; n$ I
tmp,parent=self.rb_search_auxiliary(node) 1 L/ {' G' ^: T. }# L1 g: Y+ o! V/ k! p
if tmp is not None:3 C6 D N: e8 e' `& ]4 Q
return 3 J% w5 Y% s1 H8 ^+ t
" i) k' A$ M7 v- ]! O( R+ j
node.parent =parent 0 p ^# W- I6 T/ }% g- B( Q* Q( L; L node.left=node.right=None1 f$ E+ A+ Q9 X( d) H- i
node.color=RED 2 ?; s9 B% q! T2 A4 \1 N ; n0 q. r( W H" S1 f9 ?- v, D if parent is not None:2 W0 I8 ]! P& L+ ^/ H
$ M$ W7 S! ~/ L% H" N, ?8 K
if self.cmp(parent,node)>0:! A, Q- z/ e% \" K4 \' S: c9 E
parent.left=node . i! t' W6 z) s else:2 M- @! [* \3 F E
parent.right=node 9 b8 p ^ u0 L# e# i q else:' M4 D; t- g. C" v' s
self.root=node( k- \; v) u/ e2 P* B) ]( ]2 P2 o
return self.rb_insert_rebalance(node): @. @/ z/ J1 K) s2 c, n6 X
- @* s( `6 m% k
def rb_erase_rebalance(self,node,parent): ( A6 t$ @+ H4 J: V! Z) e while((node is None or node.color==BLACK)and node !=self.root):6 |/ M6 I. [# s9 \2 {8 ~2 U
if parent.left==node:8 I* E0 I4 [5 r4 [
other=parent.right 7 _$ i8 x5 z9 A7 k( K9 Q0 S if other.color==RED:$ m% E0 u+ h7 Z
other.color=BALCK ' ^, W, N- ~& J parent.color=RED, |( N6 |- m/ n! x
self.rb_rotate_left(parent) : r! \/ [% i6 y' v( b* K8 ^ other=parent.right ; N6 N3 K' y: H$ j. h% b4 A if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color ==BLACK):5 v. J; e" q% B* \& {7 t5 j
other.color=RED; |+ t" g; z: U2 @5 g
node=parent( A0 L" R1 _4 m% @6 p% O
parent=node.parent/ x k6 ]" i" p% [% O+ X+ A# r
else: % m3 Y v" {5 C# x1 @( ]) h' I if other.right is None or other.right.color==BLACK: ; G+ D4 w) t7 G0 j4 a; m- Q" h2 s- t! G" a
if other.left is not None:3 w: d8 v. m: x9 Z) s* |- u
other.left.color=BLACK; s9 {( E7 |7 m; M. Q. o
other.color=RED# [. a& K) W; o
self.rb_rotate_right(other)8 e- H0 U& k5 u, @- |7 S
other=parent.right 8 T; j7 s8 @2 T; R3 _* Z7 x' k; @. W
other.color=parent.color) N# }$ a& _( q
parent.color=BLACK7 Q' o( ^+ ]( O4 J3 X" {
if other.right is not None: & k; G Y6 ` e" L* z5 c other.right.color=BLACK / n2 ?/ H- E$ S3 I* M) ^/ `4 |0 z5 ^; N1 @ self.rb_rotate_left(parent) 6 ?+ B( n U9 y* h node=self.root # i; T1 O5 m7 K" v break. D4 Y ] B& n" Z" v) [
else:: a4 X5 J+ d, Q4 a$ R9 d) V1 Q
other=parent.left' q3 b/ c5 j+ X7 F# P
if other.color==RED: & K" d( o3 w' H, ^3 j: a( j4 r) c other.color=BLACK ]! N) f" ^6 P
parent.color=RED $ b2 b `8 ^3 Z5 ]0 U self.rb_rotate_right(parent) 5 i9 I) O# P2 _* T0 c2 r other=parent.left # Y7 b& g( D& A# E, d if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color==BLACK):$ @0 ?( E8 B' P5 y
other.color=RED : j5 G7 \! F' O$ U6 v/ F node=parent 6 U2 x# k! u* T, [" O" n! w parent=node.parent+ Q! M4 g' [/ ?; Z+ |
else:4 b1 k1 _9 r/ M H4 k8 g/ A$ u
if other.left is None or other.left.color==BLACK:2 X0 G4 i3 k* z
if other.right is not None: ) C2 X; b% C# [# ~: a/ S other.right.color=BLACK: `4 U G$ D" b% o( G3 x' \
' X! J$ e6 X$ N" d" } other.color=RED 8 [+ M, t1 Y! L0 @* n! T self.rb_rotate_left(other) : s( L0 p* g2 l5 p: a' _. T other=parent.left 5 P2 s' Y7 X+ z5 g3 P3 s; w 0 e7 t+ j) F5 j9 `8 J: |5 S" I other.color=parent.color9 B4 l7 |/ ]+ ?3 l5 ]1 i2 b/ m" W
parent.color=BLACK1 k1 v) [7 t7 `' W6 B: a# z+ A& D( z
* `) P- O! ~* c1 C0 C: A if other.left is not None: 9 }& p0 B8 U4 D9 N other.left.color=BLACK; R# g4 b: n& L' o8 A
* |1 C3 X' `5 K6 G# C
self.rb_rotate_right(parent)4 [1 {( V2 C9 |4 W# ~* s( f& `
node=self.root ' z* b' b4 T8 O# `8 B break* C9 M, m- Q! @2 |4 Q& `
. ~2 _. B! G2 \% |% g( f* O- b' {# x9 T8 B n2 W1 z" T
9 L/ [( ^& O+ S& I! {6 I' D, A$ p! G
if node is not None:1 t5 n- ]9 m' j0 T( @. H: N; p
node.color=BLACK - `6 E; ~8 f3 L # n/ L4 F% D2 t def rb_erase(self,data):* m$ z# s! z( g' g
tmp_node=Node(data) 5 {$ [ s- H! D3 T- Y% u node,parent = self.rb_search_auxiliary(tmp_node) " _: k ]! D/ i6 s. f# X, C: W if node is None:" N$ ], C1 H$ c0 M! {& Y9 l
print "data is not exist."! R, n4 y# h7 s" z8 C2 j
return ' P; ~* i$ b1 F" k: D $ ^* q/ `; N1 V& E8 n& o old =node H" W+ f) {8 s. s+ f4 X, _
if node.left and node.right: 8 M* s. f+ `" T5 M node=node.right * n1 m8 S+ l. p5 F5 b 4 s8 A/ v% P! |* g5 S. _ \ left=node.left , d% P) N2 X! J# p while left is not None:4 D- h3 }% M& C0 @: \! @
node =left 0 u( G3 D) D5 `: X5 y% ?+ n left=node.left # S, B# W5 ]2 s+ L 3 d/ D& r t$ k' k6 ?/ @5 t child=node.right ' P* B8 N7 @" m& P parent=node.parent 2 d4 \' B, o7 r color=node.color$ W# T) u U- U m
7 `3 l( T( {. w- H
if child: / a( t j: j1 N3 H$ N- {1 R child.parent=parent 9 I: |# U7 d6 ]( b* l; Y if parent: 9 @) D8 |. y- b3 L0 I; c if parent.left==node:& X0 o9 R3 S6 K
parent.left=child : R1 e c+ k; m+ V- q else:2 f' J. F0 \# |
parent.right=child4 B/ P/ t/ K4 F& p$ \
# l* a0 h. K0 y( c+ \% C& F
else: 8 V% a2 k, m& ?% f" w self.root=child9 w( F! o/ J4 j# }. C* F$ l2 h
" e' K; P6 t, ~/ p! I# F( y
if node.parent==old:3 I" C2 g5 H9 w9 M- j0 M1 g
parent=node F* _0 w3 V' \! ]6 M0 b' a# |0 M
node.parent=old.parent 3 {. H3 ] l0 C. F' m5 s( X& C: q F node.color=old.color! R! _8 w. N1 ~+ c
node.right=old.right : q$ O2 Y% r* N+ B+ g0 a node.left=old.left 9 j* ?8 L4 l7 c+ n3 {, S' x \) @0 x( Y 8 }9 b5 a( E+ u+ i, t# g if old.parent:& Z$ y6 C. N5 ~; p, e
if old.parent.left==old: I. b! V3 P% s
old.parent.left=node( q$ q) ]' Q5 U9 F, q
else: ) @/ B6 B2 V) b- J' l% O4 T! h old.parent.right=node9 |# u: D4 s0 C4 a1 u
else: 3 v" \' F/ J C. N7 d self.root=node 5 ~8 t7 ~/ U3 I* l U 4 M9 {: R" u1 D! p) I old.left.parent=node- g5 v3 l2 D8 b0 ~! g
if old.right: ! K& x( @" e2 H8 g$ C old.right.parent=node 1 i/ S/ ~$ b4 R: G: M% r0 E2 T6 Q& @& q- Z5 R
else:% H3 r3 B8 Q/ `. b) `
if node.left is None:. U; l) E. n! w3 o" e, |
child =node.right( s" u9 `( k; a9 [, R; r, s
else: " v; C1 Q! P3 J( L% [# H4 { if node.left is not None: , |% y! w" q9 Q5 ?4 } child=node.left - O) X! L% B% u! b1 N$ N) C1 } else: ' C$ ^$ U. ]! j7 C child=None # \5 i* h, [- N/ d8 O parent=node.parent - v0 @% u! a7 K! b color=node.color 9 P- _8 e0 }: `3 v if child: ' N" O$ l& A. x3 i child.parent=parent/ x. i/ y" ~! B, _
if parent:( Y! O2 J% M* m2 K: n
if parent.left==node: 4 I B! A& w+ C- Z6 ?$ y) ^ parent.left=child 3 Q8 J* F7 Z2 u& b; k( y) T; s else:4 c7 a) a% o: ]6 u1 ]
parent.right=child# q6 F- f# |) O1 F
else: $ g" h+ U" G3 l( ^$ ?; g self.root=child' ^( V G S8 ?
% N( ]/ a2 H& L `; f3 x if color==BLACK:; c: |" u0 n. r" ^% o
# w- T B. k3 c) d0 D1 m& f9 X: X self.rb_erase_rebalance(child,parent) * r f: \( |' `+ I1 g( v2 x t0 n9 B% W& ^
4 F, q. T' I X- z$ Z2 }5 y2 K def rb_travelse(self,node): ) P1 [. ~$ [$ P- f8 J if node is not None: $ y; q7 f8 J/ `+ _ print str(node.data)+'\t'+str(node.color); }, H' U5 G& a' i- r$ B" }1 m
self.rb_travelse(node.left)" o3 |. n T7 r8 |1 ~ w# x6 c) q
if node.parent:3 [3 J1 h( d% N
if node.parent.color==0 and node.color==0: # Q- c, D5 L# f print "error" $ {# J f7 @7 G# |5 ?& X* M% P return ' Z: \8 x9 Z7 | self.rb_travelse(node.right) 2 l2 X3 z; `) v3 e H! L# q if node.parent: ! H5 _' E" k/ G3 \4 k* L if node.parent.color==0 and node.color==0: & V! V! F. m! @* X- }1 f print "error"/ l- i- M7 ^$ y) y
return w$ a: m2 V% \& ^2 q# Q7 r7 P# M
7 p! U z2 Q' ?# R$ g return ' U* C1 j7 n* {- I7 Z ! J" T8 M, l' `; O1 v9 g0 g ( Y; t5 Z. }5 z4 b' r3 o8 _
def cmp(self,node1,node2): 1 O2 p! {5 l. H$ ]6 B3 C if node1.data>node2.data : , w' A0 |& a3 ?# n return 1) Y: ?) h. a) M
if node1.data==node2.data :, J7 K# F0 ~$ R }! D& J
return 0 1 ^. m9 Y; u/ C9 M, f% d3 i if node1.data<node2.data:8 K* u( F( Z3 A
return -1 . h! _, [9 f& k- s5 ~0 d, A 8 s3 ^. M1 r' u7 Eif __name__=="__main__": - T: _* U: D" S; L6 f7 d print "main"! B5 u9 b E% Q ?( w
data=[28,6,39,78,6,43,61,56,71,38]6 X, L" a- O; Q% `
#for i in range(10):2 E/ F- S3 h6 K; Q6 x
# rand_num = random.randint(0, 100)6 {: A' i; N9 y' K) k3 A
# data.append(rand_num) 3 ^+ W6 a' Q; X) |3 G8 f #print data % ~" y% u! c2 Z# S8 G( N- |# k t=RBtree() # w+ N' I# y! H6 X. b% ? ' K3 ?9 I' K2 f4 v& w" S* O2 h) A% D3 r7 O: j: V
for i in range(10):) x# Y* l& E2 J% k! u+ ^
t.rb_insert(data[i])9 G/ `1 t R1 s' n8 }" w
5 l1 m3 W7 I& m X3 p 4 N: s. N8 h t) l) U t.rb_travelse(t.root) + P, `" F" m" |5 @8 D$ {6 B+ \ 0 _# Q2 Q: ^8 W) s print "---------------------------------" ) r" l5 S6 o2 G; e5 [ t.rb_erase(data[7]). y. z9 x q2 u( w* T
# ^$ X: f- |& f1 N& i0 A5 t
t.rb_travelse(t.root) 7 v$ b3 B- q% l; g# e6 h @' |3 Y6 Y0 n2 S( w