" M8 n0 ~+ k/ u) Timport os & b8 H" u$ C/ P( fimport random # Q8 L# z% V; n- F: E) \* I3 I( H# w! r" t/ [* C7 R
RED = 0. y4 V, o @7 g( ]) i% |2 |% c
BLACK = 1 p& u% S; f9 v5 X9 y( t& @/ o2 z& `$ t5 O! C6 i: ?
class Vector(object):, D! [8 L, ~, k/ |
def __init__(self,x=None,y=None): / {3 g: P$ v4 Q3 [1 R& r" C self.x=x & S9 w' Z7 D5 H" v! R0 i( H self.y=y$ d* L$ M+ j' @$ j2 M6 u
' s' P$ G0 U1 l# a+ C+ k. f. O, s7 Fclass Node(object): ( A. K0 X8 A7 j% J9 n/ S+ V """docstring for Node""" K, f A+ ? T0 B: [- B def __init__(self,data=None,color=RED,left=None,right=None,parent=None):* j$ W# x1 q, P" a6 [/ l A
self.data = data 0 q# K4 j- `3 m) P self.color = color8 Y9 n! P2 v) S: l9 V* ^7 b. J9 X
self.left = left , i+ A @5 i0 x9 q# |( g5 G self.right = right 9 E$ }7 c* w3 B4 n* b self.parent = parent, ?! X. l* M1 x6 F9 n
' b$ \6 z. O9 j& H& C" q0 Q( G9 Rclass RBtree(object):$ U i7 {4 T5 D9 {& w$ _& z8 N2 L
def __init__(self): ' q* B. P& A( m/ O: G self.root=None 7 q3 ]. `) x1 V self.size=0 r! |( H: S( R! Y$ M " `+ @; b; q4 E' P def rb_rotate_left(self,node):: E' a Y8 R8 p+ [
right=node.right ) G T4 l6 Y% G5 Y6 W, o. s! b1 Z9 R
node.right=right.left1 s) n& O: _1 c, N% c8 ^/ @4 o
if node.right is not None: M3 O. c$ L4 W7 S6 X& b( @
right.left.parent=node $ e& u% r$ E4 b+ B; o( @ 9 U. R$ B* I0 _$ R% B9 `% p right.left=node! X6 ^$ x( |4 G6 j0 a: v0 H& @
right.parent=node.parent % \# f3 Y+ m6 P* x% n% ]- ? ' O3 T R2 ]; w0 q if right.parent is None:" B7 x% c" W$ T+ [2 v" p
( G/ E' X3 G1 v& K% f
self.root=right + M& n+ q; }' Y I" M else: . W8 u7 t% o9 f! I$ y% ^ if node==node.parent.right:0 O* \0 l" H$ ?
node.parent.right=right; s4 o: I$ x3 ]! G0 z$ F
else:6 x; o1 _* V4 b ? f; p8 G. Q4 ^
node.parent.left=right / V* a! D R" G( D node.parent =right 4 O0 b8 \, C( x% ~" _! l2 o3 C : V- d Y7 n- I- l5 Z4 p: o' K& _! C' D
def rb_rotate_right(self,node): # [2 m1 O5 j# M- x. D7 h left=node.left$ ~) b, }' @2 w: P" I
node.left=left.right: @5 c: ^% h; U! q9 Q
$ K% I' k6 s. B- J1 O! ]
if node.left is not None:. J1 e2 v& l# b. Z+ W3 V0 O/ _
left.right.parent=node ( D# ^. l: a' `6 m: m+ E# F5 W6 r8 Q7 X
left.right=node0 s3 \* v& t2 x. W9 o% s8 \# i
left.parent=node.parent) U! A2 C5 f, ?2 e) v, T) e2 E
- z( d. U, _ r% e1 S0 W+ a
if left.parent is None:0 `2 ^( Y: y2 ]+ e
self.root=left ' N( s4 o+ `& J) |8 y# H8 a else: 6 W1 v& y; o, @4 i if node==node.parent.right:7 g$ |7 K4 f5 N. E6 L" U
node.parent.right=left ' M4 z. b2 g% m4 z& u; G else: 6 u7 Z3 p1 B: F8 f) [ node.parent.left=left & N) M2 }/ c1 a$ O node.parent=left) [ Q5 G4 x7 s' J& L" l% Z
6 Y3 i. b3 r3 M def rb_insert_rebalance(self,node):$ V/ T+ m( {, N; r9 h7 B2 ^
parent=node.parent6 ?. }; H) ]7 S! J! K
while parent and parent.color==RED:9 ]' u5 a: @: L3 G1 Y1 e; Y0 B3 Y6 l) B
gparent = parent.parent" X. }8 S4 w4 R2 U$ f8 R2 n4 n
if parent==gparent.left: 0 K/ {; n( ]2 ~6 G uncle=gparent.right2 Y( j, ^! T) L/ a$ ] ]8 O- @" \4 u1 v
if uncle and uncle.color==RED:( J9 |8 [6 @3 k5 s" e* F1 `
uncle.color=BLACK# s$ g. U ?3 _% e0 M. D% b5 w$ A
parent.color=BLACK 2 h/ e- R& P1 P9 \6 |7 c' Y. ` gparent.color=RED " z8 O3 D [: Z node=gparent 1 R; ]* q$ _# ^3 W+ ]9 B else:- U1 d& U& f/ H# ~+ r& F6 ~
if parent.right==node: * I% `3 [* F/ q/ P! u self.rb_rotate_left(parent) % M' g% |* _& ^/ S tmp=parent ' H0 l* g$ E* I( ?. W4 W% ?5 \ parent=node, a \" D- x Z$ ]9 H
node=tmp / |8 u) j- P# z# c) O' d parent.color=BLACK: F1 p5 E" G8 I, D
gparent.color=RED7 B3 k% U8 V8 j
* D6 _ }6 E; V/ v- z
self.rb_rotate_right(gparent)5 p% F8 {5 A5 o( o+ A/ z0 @/ k
4 [; j3 u# x; \; H- V- | J5 R if uncle: ) H j7 I7 G0 N) s) Y if uncle.right:0 |8 G2 s: B/ G
node=uncle.right ( j: k. z. T; A- G& j else:7 B& r: {' }8 Y' V" U) V
uncle=gparent.left . T1 x A3 {5 X1 X: A+ t8 |3 e if uncle and uncle.color==RED: # t, ~8 B4 }, G! X+ v uncle.color=BLACK $ G- T/ d# N/ d8 T parent.color=BLACK, N4 y1 h! z, @5 v; k4 ]- i Q
gparent.color=RED5 T9 _; T0 E' s8 \ a
node=gparent( x5 t5 C, Q' s* H% A9 t- o6 d5 k
else: / ? r. V8 H8 s# G3 [ if parent.left==node: * `" z+ p8 y% w1 I self.rb_rotate_right(parent); b7 l) o2 ^ H/ `8 Z: ?8 ] K
tmp=parent& z. W' F, n0 [5 D
parent=node 9 K+ ~- U9 V) d+ y# v node=tmp : O1 x- k8 W6 M* v. I4 Z parent.color=BLACK: H: [) C5 R1 d/ O' n& \: @
gparent.color=RED : [" j$ l" [7 Y) Q self.rb_rotate_left(gparent)' T) T4 Z4 B. w- ]: e! o
( Y) |9 N/ J* [6 y2 F1 a9 u if uncle: 8 y: e! k' }+ Z( ^+ K( P! L- S if uncle.left:. F4 p6 c1 R* i- D0 A4 H
node=uncle.left- O' P/ j+ ^9 r' N
parent=node.parent 2 o% q, d) @, u d1 H8 i& S- T! Z$ F& Z5 [0 J t4 _
7 c! ?1 K$ ^$ F$ J self.root.color=BLACK 3 f+ t6 T3 j: U% a% w9 G 3 q3 j. w) K- K$ N/ b2 M 1 ~5 e# q8 \/ ~. f
def rb_search_auxiliary(self,node):$ M( \; Q7 H8 x* h: C
tmp=self.root $ x, W5 q% g) a: }2 b parent=None ' |# E- T% T( n* E5 A while tmp is not None: ' o# g4 V& L. f% T& M parent=tmp9 q) F0 e/ k% z$ ]: j
cmp=self.cmp(node,tmp) ~+ x/ E% H1 f0 E3 a( q, w6 e
if cmp<0:+ A+ o- H6 |3 q
tmp=tmp.left7 w3 f9 ]4 j: b7 v+ m* E
else: 1 x$ ^) A1 G( B3 v( Z* w& K" W if cmp>0:) y, O% V/ K& Q( l @4 v0 P0 b
tmp=tmp.right 0 F; ~$ Y$ Q, |- r+ z* I) \ else: # `* B9 B" ^$ Q; v: v return tmp,parent# s( h3 s3 z- d/ L5 }- ~1 M
" v. W5 r4 a9 b% R return None,parent' D+ L. S5 _0 \' d
% j5 {5 M; {7 U, R* O$ P1 @
def rb_insert(self,data): $ l2 H1 o" G( J3 R2 d tmp=None # B. @ t* |' q7 S6 ^+ j node=Node(data) , F# E% S4 l4 N4 D) G L tmp,parent=self.rb_search_auxiliary(node); y5 x3 X/ V# l' O5 b5 T3 f( g
* a+ w9 j$ \0 X( S- _( j
if tmp is not None: 3 ]- i+ t$ o7 ` return 6 ^6 c: i F2 o' y$ ^* L* ? p3 p
node.parent =parent - R" V2 a6 V" _: a% Z) U1 n node.left=node.right=None9 P$ a9 m% I- A7 {
node.color=RED) z' O# E( L( f+ P' b' R
0 U$ M+ _6 P- _- Q" a. ], ^/ D
if parent is not None:9 M8 N5 A3 ]/ Z7 p0 F5 Q
2 D- T9 X. K) [& n if self.cmp(parent,node)>0:+ v3 Z S% E1 \3 a
parent.left=node 4 C' F+ I6 B: I. |+ j else: " w# m E0 y6 _: v parent.right=node ( k) B! k7 t: ]) g/ d1 v else: " v" b- ?2 \: C: Y5 _; G self.root=node2 }1 h4 N$ t- C$ \7 l
return self.rb_insert_rebalance(node) v P, ~# i/ ]: U4 |; H$ W* {+ I# }
def rb_erase_rebalance(self,node,parent): . T9 {9 R2 C3 P, x+ j while((node is None or node.color==BLACK)and node !=self.root):) }; o" I. E+ H8 d
if parent.left==node: % y$ ]' U4 r( _! Y8 e" k1 D, ` other=parent.right 5 q8 x7 D# Y3 S5 i if other.color==RED: 7 W* r# x: P; j y2 o other.color=BALCK9 W3 ?' l4 U5 ~; I1 E) G* q
parent.color=RED * J$ X' u0 ~5 z% l, o self.rb_rotate_left(parent) 0 Z' Y% i U9 c8 Z other=parent.right 2 n' [* B) W) z9 E if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color ==BLACK):# N n8 _2 d A; D
other.color=RED " X) |. ?4 T& x; }# l node=parent 8 J% S, x, p- G- w/ F0 r* l parent=node.parent 9 z( m+ ?' s: K8 L1 P/ k! } else: / ?8 R5 P% e0 j6 U2 w if other.right is None or other.right.color==BLACK:1 K2 R$ a4 x4 b# @, v( P: b3 t
3 V0 y1 t; P) `2 m2 {# D if other.left is not None:) y x: ~% d# J1 Y, [
other.left.color=BLACK 4 m$ d' I" A" H& \ other.color=RED$ A; d& G% F& \$ f- T& M! ^1 N( `
self.rb_rotate_right(other)* p6 n" k' Q5 Z6 f) T" D9 L
other=parent.right - d+ F& x. T7 Q3 D 2 J2 ?9 ~. X# E6 u4 [. W other.color=parent.color1 T6 S7 N% s- b! ^
parent.color=BLACK4 R8 X5 l# o. ~- [5 h2 H
if other.right is not None: $ ?( p# }! K5 B' @. j/ n other.right.color=BLACK6 j- g6 R4 D9 w
self.rb_rotate_left(parent); X$ V: j& }4 `5 s
node=self.root; ^, ?( g' {6 n8 m# [
break2 w# `3 r+ u7 d" G) q+ q1 Q$ F& \
else:2 G( X5 X4 l" @/ r3 e7 f+ w8 B
other=parent.left; @: V/ {2 I# x4 h* c( F% y6 c B) c9 h
if other.color==RED: 0 F. D5 h& V$ D4 w; q other.color=BLACK 7 I i. d1 L) Z parent.color=RED 5 a* R# G4 B& ]# V# Y% w+ ~ self.rb_rotate_right(parent)# W- S9 Q7 U0 K# A
other=parent.left, ]- b) w7 @" d! M0 U4 m
if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color==BLACK):; g3 Y4 A& g" q$ j9 f
other.color=RED& W/ _* S1 U$ T3 L
node=parent4 _! y7 g. q4 i9 V8 S1 c! N9 V& N
parent=node.parent $ U. l i" ~; t f: f# I! t; } else:" V8 A( w" C; [8 j7 x7 A% j. \+ W
if other.left is None or other.left.color==BLACK: % ]) X. `+ p6 F$ ^6 L" D. [ if other.right is not None: # E, \5 ? E4 z! I3 R other.right.color=BLACK: U0 x! A7 {% L: q$ A3 N. r6 y. `( y
6 b) K7 W) n! s# Z& c3 w( i( ? other.color=RED ( m1 J1 U$ |& ~1 P+ m8 U2 L self.rb_rotate_left(other) & x5 {# G" |7 k# f- _& g! b other=parent.left% K3 K' t1 X0 K( w
# Z7 ]7 T, k+ P, s( K1 Q+ F7 w
other.color=parent.color8 J* z* w _; Z
parent.color=BLACK $ s8 p% z/ q* O% r( B- `' }! D! Z3 y
if other.left is not None:+ a5 x. S! x' u. N
other.left.color=BLACK/ C: ~, R: x y- [9 J5 M
+ v% r' w# L( z8 x7 v# B, h self.rb_rotate_right(parent) ; E: @! A: }: K$ ? node=self.root- M4 a) v0 S0 z3 Q" G" K! L
break/ b4 w0 S% S# R; l
1 T& K: P) J2 I4 L( }+ a
" Z+ B- |- Q9 S! i. ?- ` 1 Z. r! U6 y4 o1 i/ j z if node is not None: - M9 i+ D/ ~' d# [0 Q node.color=BLACK $ O/ L4 @+ o' \7 r
. q- ~) w7 n/ V. f4 e1 g3 ~ def rb_erase(self,data): m7 \) Z' T- _8 z' z0 w tmp_node=Node(data)% m# m h! o! d- _9 r: w" y
node,parent = self.rb_search_auxiliary(tmp_node) ! h8 n3 a* G S5 S+ J9 ~: M' ^3 D if node is None:- x# F8 d( x: E1 R+ g: g& z1 I. O
print "data is not exist." ) b/ F2 a9 F! g4 r/ ^) Z' Q return$ B, U! S4 a5 Z6 Z
- i0 @' H) }$ J4 `" y' |9 ]9 \4 O
old =node , `4 E: x( D W2 |0 U n if node.left and node.right: 3 C! n5 ?( R- J( H- x$ d" F/ H. \ node=node.right' J4 T9 S6 d( g$ w' U* y
! O6 w& K% T; ~# Q- O! r& y- B. { left=node.left; x; [* B* P7 [8 N" A
while left is not None: , o% F- l8 n, F+ [) {" I node =left ; Q) v7 O8 n5 b left=node.left 8 C+ I2 w" \! i. {! S1 K - S% ]- j, g7 D7 M child=node.right$ X' S2 I+ }' n1 k& ?2 s* k) ~
parent=node.parent - v# _- V' O7 ~ color=node.color 3 V9 c) b- B) K: B- Q& ?* b' }- J( g$ z9 c( T
if child: , P$ O* C; h7 d x# {3 O% ] child.parent=parent 7 c, r {0 U3 N& @ if parent: 7 K# y5 ` b5 S. z$ y if parent.left==node:* L3 m* ?3 `* L4 }0 B
parent.left=child - {: ?8 X Y: G9 t' C4 K3 z else: - s/ e, J$ D" a( G+ p parent.right=child) r/ Q# N# D8 v& |& L1 D
" L6 U3 ?9 Z- q/ p9 k2 Y
else: " t7 }7 N7 ^" m; W/ I3 K/ q$ l5 s self.root=child' ?' |% O) t7 |
5 {! U0 |' A$ ^# T- f' { if node.parent==old:; q, w7 h+ x- R& ~7 P$ j2 _
parent=node 3 e& c4 B+ N' l node.parent=old.parent F; c' g, r4 t% X0 L3 C
node.color=old.color 7 n2 u0 S7 `: Y, `) `' O5 _5 E node.right=old.right " t+ i' J6 ]+ i" ?5 { node.left=old.left" v' V. N; `4 r! F3 k
; }) Q" w0 P& R2 K9 O if old.parent: 5 s1 |# w4 L6 z5 X% V if old.parent.left==old:! n& f v, Z) D) ^4 v
old.parent.left=node0 j) G4 b: t5 u" C$ s( x+ Z2 i
else: 4 r0 x8 c% s. {- I+ t9 q old.parent.right=node4 y# \) | W2 \4 q" M: S3 Z: o' ^, l
else:+ N) p, ~# r- Z$ E
self.root=node , X: j* V1 x( T+ ~7 Z8 D( q7 a! X( H# j! [$ t2 R: D
old.left.parent=node : Z! G/ z( G% @4 R; V, h2 Q2 c if old.right:" ]) F2 g0 z9 L! L2 A# B
old.right.parent=node % x0 w6 [3 W( z0 ~2 u) t( P+ U1 g) S, f/ @+ C
else: W1 W) a& m6 R2 F
if node.left is None: $ ?) q- I6 t7 b j$ ?0 h% i5 Q child =node.right & D5 {$ T- X; P8 `+ \0 Z% L, j else:" _# f3 j/ u$ J" o
if node.left is not None:: ?% z) U9 S! K2 ~$ W/ t, r. {
child=node.left( O% D+ r$ u( Q( ^ f
else:% e1 K7 d5 N+ U3 ?7 c. O
child=None# T- l l* Y( x% L! s
parent=node.parent ! ^0 C' T, m' E6 d" F color=node.color! e6 e1 ~! c W7 t9 \
if child: # x+ w# G! B( |' j5 ?/ n z child.parent=parent 1 j7 J7 g( S& l" O" H if parent:* l5 @ v5 i* B6 o" i, m+ n) M
if parent.left==node:7 V" n' q1 Q8 m& C5 M$ |! S! f
parent.left=child " A0 H5 f8 S! k' Y else:, E" G6 U+ n* f& v; w. c
parent.right=child, |) K0 I" E `/ x/ ^4 `8 m
else: / t# |) g7 J5 w0 ^' R' t self.root=child; I( M" }4 x9 G$ q! b
( E0 A E, p: W! `) `% j
if color==BLACK: 0 j2 G- B2 w5 h( I. J. t$ l0 Q8 D, v0 C/ t1 J8 w7 p
self.rb_erase_rebalance(child,parent) ' q4 N. ^' b ~) i3 s+ G1 I. }: Q5 y% a! p5 q+ B% A1 g5 _
e* j! K6 e+ g/ O* @
def rb_travelse(self,node): 8 R5 |4 f: ], Z if node is not None:* S# ]3 e: y6 u) Q: P
print str(node.data)+'\t'+str(node.color) & I7 h7 g9 B: I9 n& l self.rb_travelse(node.left) ) d; W' g& G4 L* a* q if node.parent: - j5 S- E* h, t$ d if node.parent.color==0 and node.color==0:0 O% _& Z- W1 b& \. d9 h
print "error" 8 @% F( ?$ b, a+ S! B% E$ j) x' B return r# [. N. @/ `" \2 J
self.rb_travelse(node.right)' g5 B& Z T7 e, a6 Z' ]
if node.parent: 9 ^/ }# o' `" Z/ ~$ k* D. I if node.parent.color==0 and node.color==0: , l* s- k( y0 t( j5 X; G: d7 a' q print "error" ! W& `# J5 ?# U7 [2 `2 I return4 J. q) ~6 z: n# V" U
5 Z9 @* l( m: T' P0 |0 _+ d' G
return0 v5 P, Y) ` v
# y2 a8 F- [( ? 9 \0 `/ R' N! l9 f4 M2 s
def cmp(self,node1,node2):8 b* f. N, A, f$ B, s
if node1.data>node2.data :" }0 c4 x; Z* V3 k x7 `
return 1 ) U/ M( l1 o) h. e% C# i# I5 | if node1.data==node2.data :$ U1 {" l/ }2 L/ @( `1 b
return 0 % N. T5 _4 o" f! O if node1.data<node2.data: 0 i( f. n8 I8 E6 R return -1* ~* l; E9 e; Y% c4 v& a3 u
' N8 B$ X$ W& c7 h a
if __name__=="__main__": $ b# r" d6 z5 h" e' Q3 y' Q. f, U print "main" # S. [9 i: [$ Y1 \6 o/ {! ] data=[28,6,39,78,6,43,61,56,71,38] ( o, _# t/ V& Y1 F1 L #for i in range(10): * V0 F+ |3 U3 }' e. ^/ a # rand_num = random.randint(0, 100); B! H* Z$ P0 z. z; V( z) i/ ^
# data.append(rand_num)3 B( f' _2 P! U& f/ ~8 N3 I( {
#print data 8 h8 I8 q! A! i/ Q/ f# p* G1 O t=RBtree() ( k0 E+ r t# c4 m! D x5 P; x" l. b" c
/ L/ X5 W2 x- W0 R- M: J for i in range(10):9 B- t k5 R) V8 o
t.rb_insert(data[i])4 y, |3 T9 s" p* a' G
8 U. j: j- w& m( _ # T' L6 k! Z3 J3 V z6 ^ t.rb_travelse(t.root)% q9 \6 n& J% n! I6 M9 |, N
' e7 c, F5 v W, F3 U. y) e
print "---------------------------------" 5 L4 G) y8 m% l t.rb_erase(data[7]) ( }* ^& q- r6 K' H; C) ~; J 5 x* r! y9 U9 A( }' ?, ? t.rb_travelse(t.root)! U4 g9 g7 g& r+ b% f& i
- u' h5 b& q! m l) o9 m) {* a