: X8 W$ h, }; Q9 B2 v' V2 Y" Qclass Vector(object): 7 _+ R$ o1 l* H6 a! D def __init__(self,x=None,y=None):2 I+ r8 y# W) V- T" P: L# C
self.x=x( C+ F7 `2 c" G1 M" M$ A
self.y=y! J* Z( H8 p0 A3 ?6 L; h
1 l$ t- L2 o7 `0 ]+ z/ P2 X" z" k
class Node(object): + `4 B( l; e) C6 g$ o1 s6 D5 I """docstring for Node""" ; B6 @# i4 F: K' c def __init__(self,data=None,color=RED,left=None,right=None,parent=None): . t' h! D( k6 s! L4 q( [ self.data = data6 [( c- r5 W% H4 t
self.color = color o9 P( I" n% s
self.left = left: y3 [9 |4 p3 s1 O* n3 U, p7 Z7 r
self.right = right. j1 t q' o$ a4 b. ]
self.parent = parent 9 {# d* o* \: H2 e- \* c6 K & ?( K w- o: U! O7 Cclass RBtree(object):5 r$ K4 }' X1 w7 x, C7 _5 E! X
def __init__(self):' ]5 f5 c7 d' g) Z. p
self.root=None ' I6 l" m5 L$ u. L self.size=0 0 _* O5 l& D% C3 Z0 G' A% U/ a1 Y+ Z' `, h) W
def rb_rotate_left(self,node):1 W5 m, p9 O3 r2 p; O" r! U
right=node.right 0 F* G* v# A1 H* ?; Q1 B # {; b# m6 O6 T* V node.right=right.left4 E" w6 ~( G! f9 z
if node.right is not None: $ h7 G# g; @; c) n& G right.left.parent=node & s* G' H! |) z+ ?& F ! g; h2 a: y/ \& R4 ]; c right.left=node3 d; U) s! d' B" } r# U
right.parent=node.parent & X: ^5 Y. K7 ~, c- ^, w, ] & h& {+ a- a- |! v! u if right.parent is None: 5 p" E( z+ [' _) g/ h X" }# B4 q: B0 {6 U self.root=right 9 b1 n4 f5 p' A8 e' _. l else: " d8 m: Y& q3 ` v% K& F% @7 z if node==node.parent.right: ! U) _* u3 W/ ~2 f" n" v node.parent.right=right & J2 r# h. L- U# Q% Y, b3 k/ B% I else:. C" i0 e! X& x, N
node.parent.left=right8 }* S" @) J: _! h
node.parent =right . c9 P7 r/ y, j n0 Z8 P + ^$ A6 @5 z, [: l- q# ?4 T) z- V+ ~0 W% n6 u6 u
def rb_rotate_right(self,node): J' G3 K+ _: e; d- B left=node.left , g2 M, q' [6 I& b; _ node.left=left.right* r% R4 [3 Y! R, V7 Q4 t( [
, N0 [2 t0 s4 v: j if node.left is not None: 0 [/ F9 L' k; m- O left.right.parent=node3 T% o: X6 j/ t( \% P7 C3 g3 q
# _1 I/ L- O, ~2 R
left.right=node . o; `$ Y9 {7 I1 f8 ~0 \% z0 @8 p! i left.parent=node.parent/ N* C! f& S P |1 D# p, L
4 J# K9 y) k! w: x6 \ if left.parent is None: " W1 h2 |3 r+ ~ self.root=left3 X2 ?+ O( L( ]
else: ' @, @$ e1 e+ w6 H if node==node.parent.right:" t: A# l& O, X9 Z) C! `* F
node.parent.right=left % k* x" f) C3 D2 @9 U else: 7 W% c, O3 N/ Q; q$ z( p node.parent.left=left( o ~6 W- {$ e5 E
node.parent=left. l; m3 \: F7 l# m4 K
* _ h' j* v) L# d/ c% S/ I; Z def rb_insert_rebalance(self,node):; L6 g; p$ W: n3 s! J
parent=node.parent + F8 `2 i; i, r while parent and parent.color==RED:5 C% r' c a* v( M4 M4 O
gparent = parent.parent ( T+ U5 h) o6 E! y if parent==gparent.left: ! U. i' w7 o4 ^$ g- [+ a; Z9 u! a% D uncle=gparent.right& d3 v; b) X2 s, @) l( Y# a! i6 X
if uncle and uncle.color==RED: j( U. y/ f0 Y2 z$ r uncle.color=BLACK ( x8 g1 [) t( U parent.color=BLACK* H, |5 U/ `# M! Z5 \3 p
gparent.color=RED/ U0 g" \/ {2 ~7 z! G. K
node=gparent$ {! z0 q+ r3 E6 K& R! V
else:5 S1 o z; P. v: `$ v/ Q7 @7 z. |
if parent.right==node:& O' V% \4 }" B9 e* @: Y
self.rb_rotate_left(parent) # u: A4 _" ~6 m/ g tmp=parent! M6 P9 | ]; c- C( z
parent=node 9 Z# ?" ~+ A* q& p! R) H B node=tmp5 W, e' s; P3 U: t& g0 F. F$ b
parent.color=BLACK0 ^: m4 ~- S% o
gparent.color=RED3 Z" ]0 ~' o/ q6 M" x
, ^' K! _8 G9 `6 G2 [4 c, P
self.rb_rotate_right(gparent) $ V4 `. ]. v9 L8 U* w, }% }1 k7 g" O9 N' R" W. h6 N# D/ \+ v
if uncle:6 g0 y0 j" Q: ^9 F. J
if uncle.right: - k+ b) ^6 w$ _* |8 K node=uncle.right7 p* L. V+ C' n4 h* T! R
else:* E0 @' r8 |! N2 h
uncle=gparent.left ' H' y6 e3 t' j0 \4 o if uncle and uncle.color==RED:" Q) h' {9 u1 N) c
uncle.color=BLACK9 V1 O/ F- r/ ^
parent.color=BLACK ; u- `& I3 m2 R2 N gparent.color=RED ( S0 O0 n% x+ G( b3 m& Y3 H node=gparent 9 o. Q5 a9 u3 o4 x) U# | else:1 @6 }$ O" Y) m2 t0 d4 j6 M
if parent.left==node:% T# _: N/ M- ~! l, `' H
self.rb_rotate_right(parent)3 b6 T, ^' f( q# w @6 j. U/ K9 h
tmp=parent8 j1 w( f1 G/ V' \' E
parent=node + |3 s: _. v: O+ w) e: l node=tmp ; b1 M i9 u6 T7 V parent.color=BLACK- o; [% n5 E6 [) C. j- F4 t( E
gparent.color=RED 7 y; X, o/ i1 A$ j3 L, N+ S6 M4 X" c2 _ self.rb_rotate_left(gparent) 0 Q3 m8 \7 `. E9 Y. O . J, Z' z9 w7 T1 R/ @+ r; e+ T if uncle: & |) A+ ~; C5 B. I% \ if uncle.left: ) T' X0 D; p0 X# L$ R% d4 c node=uncle.left 6 T6 ~$ {! E9 m# `+ ^ E- x parent=node.parent . p# V9 R: d. ~* K" g2 @( I / P: W: p B+ ^8 Z 8 }# z7 `! F; m/ c) I self.root.color=BLACK: Q3 P. w( ]6 i/ u. @/ {
) m$ W y5 R) s
; y3 U# _/ ]: ~! \. ~
def rb_search_auxiliary(self,node): % h7 G8 \! V( X0 i; ] tmp=self.root6 I$ L0 }% a/ ]' ~" t1 O
parent=None 7 }' V. y6 c# T/ e0 g$ | while tmp is not None:+ _- M A5 ~" }* c9 j) n
parent=tmp 1 k7 N) g( X* J) X& Q cmp=self.cmp(node,tmp)/ F O/ \7 i4 A" ^' c5 Z
if cmp<0: 9 n! m5 C) \. ^5 V tmp=tmp.left: S$ d @# r0 c/ z" V7 l
else:" n$ G2 _, l$ B1 S, d4 _
if cmp>0: 1 n* Y' X) @, Z, U H! N6 t C tmp=tmp.right- i/ q! ?( C& c/ `
else: ; `7 F1 l% u! d3 ~4 P return tmp,parent 1 I$ q5 F8 _3 U4 e6 R7 g: o; u7 K3 J/ N
return None,parent; r' H' \8 ~% B: M
3 d! {5 w9 G k: c! N# E def rb_insert(self,data):' j& C0 Y% C: H1 u9 L; x8 @; l
tmp=None z! }- d3 X6 P3 C; Q, n node=Node(data) p/ @) D& x2 y0 |; ]6 b tmp,parent=self.rb_search_auxiliary(node)3 A0 L5 f0 J4 K% z; ?
0 A, F Q3 S! E( k9 b7 m if tmp is not None: / \! {+ E4 g3 y; z. T! u! ? return / J$ b {* D$ n0 e3 y- w
, ^" T8 n! |4 S( v- C/ F7 l node.parent =parent * G5 _& f3 C$ C" _2 ?4 a5 V% O node.left=node.right=None' _0 Y1 g' w) s* K* A, G
node.color=RED B/ Z: ?! X) J. \/ P& V% u# M D `8 C: Z
if parent is not None:; S" A" h/ D8 ~3 x0 e0 c' y9 u, t
6 ]4 b. n# G2 d4 j7 F
if self.cmp(parent,node)>0:7 F6 l, f4 F0 W' J+ @& p2 B& w1 n6 U
parent.left=node, c5 Y+ i2 t+ P
else:2 K/ b0 L- s: H- z/ J
parent.right=node " h4 F5 c. c. f; S! s' e else:: _- j0 O9 a) q" i
self.root=node 5 ~, e6 K# L: V7 { return self.rb_insert_rebalance(node)/ q p" v7 w( h! n }% G/ b5 U3 I
* w& v$ {7 x% a8 B7 X8 _% c
def rb_erase_rebalance(self,node,parent):/ D! W7 X; K0 h# V; K
while((node is None or node.color==BLACK)and node !=self.root): ) n C' T( k. t( ]/ g if parent.left==node: 8 U, C7 j) N, h4 s v" H$ j" E; f' O other=parent.right& z, r7 k' e1 Q* W. {8 x( i
if other.color==RED: ! {2 g3 ~/ ~ A4 ~- r6 d2 Q i other.color=BALCK0 y5 R2 U- {/ r8 m
parent.color=RED % M. R, [0 i, s1 P: S self.rb_rotate_left(parent) * @+ z7 u( W9 W! C; | other=parent.right6 N* C( m- L$ `! R' x8 M
if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color ==BLACK): 5 `' _ Y/ R& i, q other.color=RED ; H# j R, Q8 ~ node=parent & Q' R" x3 C! N; g5 Y$ D parent=node.parent . r# t0 h; R6 G8 s) J i1 v% D else: ! k9 d/ `7 ^4 A8 ? if other.right is None or other.right.color==BLACK: 4 @8 A/ g! T0 ~; N z$ H , @# D9 S4 T: a3 D if other.left is not None: 9 p I1 X/ m6 N& v" q8 ^: M' Q9 \ other.left.color=BLACK ; Z' n9 `8 t! n. b. i! H7 n5 z other.color=RED2 w8 b* h8 j, R& X+ f& y! s% [
self.rb_rotate_right(other)- K* B* g# Y2 i E. A7 G
other=parent.right; M4 X) ^) D7 n# Q) E, m5 R/ M
8 j9 u# s [- d8 f+ g
other.color=parent.color 5 T$ P% Y @0 u" T parent.color=BLACK/ E2 ?+ H! h3 v& ?3 m+ M# j
if other.right is not None:9 n, b6 ~% [6 `: d& M* b
other.right.color=BLACK & Y4 f1 d0 B% n6 P7 w: t1 ^- k self.rb_rotate_left(parent) $ M1 i% W% P6 Y4 P2 T node=self.root D+ z" B( [1 K% Z4 r
break / [. n% i) l' b ~: h9 [9 R8 ]+ `6 y else: 3 q' L: Z N, z0 ?& ?; i/ ` other=parent.left) V6 Q4 }1 k, ?5 r) m
if other.color==RED: & Y8 o. N# D! }4 } other.color=BLACK0 H6 n/ U9 I& s7 M$ s3 s
parent.color=RED + c+ \# j7 {- K) S4 k7 ?) q self.rb_rotate_right(parent)* S7 S" q9 X" L+ W
other=parent.left 3 n/ \* y" y' p" V. K$ N1 y if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color==BLACK): 0 e- p6 T: ~4 O0 l; j) _# t other.color=RED& V' B9 ~/ e( E+ i d& l
node=parent G0 h4 a! o3 B$ y# T( w
parent=node.parent 3 V) V1 y% N( c, @0 B else:$ p, ]& I" Y, v( \7 H8 C+ b8 ^
if other.left is None or other.left.color==BLACK: 4 m, `2 x4 s- _, I. z. t if other.right is not None:# \" e* J$ Y3 a) X8 C7 R& o
other.right.color=BLACK + q* ]* j( T8 }0 t$ g# e: f, _9 z5 r- d% n3 Z2 x! A- s
other.color=RED : \6 D) p# W3 l self.rb_rotate_left(other) : H' q% E+ N2 |# U9 M7 ` other=parent.left/ e( G4 @* L' i
. O. e7 E2 V( e3 w/ E( V! k8 c other.color=parent.color# n1 |/ _4 @3 M* X
parent.color=BLACK ! Y$ R' u. ]3 p$ ~, ]. P) g5 L1 y0 V' _) w1 [5 E' s }: l
if other.left is not None: . H" Y$ R, W4 _3 z other.left.color=BLACK * F( l7 T3 p }- v, ^) |" z, a# e* H. `7 x
self.rb_rotate_right(parent)" P% u3 B, J( T$ b) ~- y
node=self.root # _ e; s( k$ X! p7 q. I: c break6 [# a4 c$ n4 C3 u: h ^ x
8 E0 W; F9 ? _3 C
2 f; s; o9 Z! D# A7 F' ?; T- H/ k" H4 z
if node is not None:8 P5 w6 i# \9 X' x. B: ^
node.color=BLACK 5 H6 E- [- r- M5 ]) |' U# c! @- J6 s7 Y+ t/ M8 v9 y- V
def rb_erase(self,data): 1 t$ H* A9 {4 B, f/ f tmp_node=Node(data) ' z4 F5 k- v. M+ ~+ G node,parent = self.rb_search_auxiliary(tmp_node)* }# ?: f, }; F/ X3 ?' v& [8 F
if node is None:* U9 ^# [; d9 k4 W6 i& b
print "data is not exist."1 [' u5 e' t% x9 f1 q* z0 [
return/ L o2 k1 Q4 E2 z* Y2 J
7 t. J3 L$ |! O. W4 s old =node3 S0 h1 d7 P( p: f( F* r
if node.left and node.right:) y" c% L9 J2 b
node=node.right 4 b3 l9 B* F/ p7 a: [$ F ) f4 F* e4 [6 T0 ~( S9 h; q left=node.left$ b: q( B3 q0 j) i! R+ [# w* Y! Z3 X
while left is not None: , k3 K7 G: L7 }9 N node =left4 W5 ?4 ]. [, H& v5 @0 ^8 e7 g
left=node.left ! ^' j( K# m1 m& V. j5 p/ [5 N) f9 Y4 \
child=node.right. z- R# g; ]6 X) [
parent=node.parent5 ^' J7 \, y1 C3 l
color=node.color! ?7 B$ d% |8 b% H/ Y
: T0 D! e+ V* h) X0 d
if child:" e) Z. {- \' \- c4 y' J
child.parent=parent! ?; Q9 z B6 K% T; w6 A
if parent: % Z9 _7 o4 H) p2 I3 ^; y if parent.left==node:! _( R- }5 Z2 v
parent.left=child- `1 h; E; N8 a
else: ( U" ]! z X9 i4 y& L* e parent.right=child ' D* s: N7 V1 j) f X* q9 m' T+ u- g/ i4 @) o
else: 9 }: V( L G5 d- } self.root=child# ^7 y8 X; e" D7 }+ i4 [- O4 O2 T$ P
1 H) x+ r: x" M4 u' u0 c. r if node.parent==old:) _. n7 ^& T$ q/ V
parent=node+ a+ |8 u# H. [1 _
node.parent=old.parent - s; B& {9 b0 A# C4 H! b2 }$ b node.color=old.color( g/ G4 C" C9 b4 }6 x0 U
node.right=old.right9 T5 r. `5 A2 r
node.left=old.left0 i O* h$ J+ G' F) y
% q- ?. ^- }3 q* a" Q7 W: ? if old.parent: 7 d! @& i# f) I3 B% G6 l if old.parent.left==old: & h; Y" ` l4 I R6 J; I; t old.parent.left=node0 X6 h- X- x, i8 p" E6 n$ V
else: 1 |4 M* c* b: v+ w6 m9 i# j old.parent.right=node! X- p" E- Z' d* g& q! k; b
else:3 F. n4 k6 Z. ]; b- w5 G# g0 }
self.root=node3 c" N/ N* w. J9 o4 t/ O* c
- e. |1 m. Q4 p2 a, `3 `. w% j
old.left.parent=node$ G6 P. |9 O! k e
if old.right:) i2 X9 [( O! U3 F O u* R
old.right.parent=node5 V3 D5 `6 C+ Z" D3 Y
6 s* j+ k# U/ Z' R) F
else: % [" y, s& `1 b6 F* V% B if node.left is None: 9 M: e$ @5 ]* W! W [ child =node.right 3 V0 e8 l( \+ B$ B else:* N) p, w7 t9 T# s4 H- G
if node.left is not None:7 R3 L9 a% b7 P* }+ L/ ~
child=node.left ( u" @5 [+ L" X- N5 V# G# S- N else: + Z8 [. [, A; x/ {5 s child=None + P$ G- M+ R; L; j# r) p" b parent=node.parent/ T7 Z& l. d/ v. T6 P; l1 T, G
color=node.color1 q, k2 ~) C9 K- E$ x, T
if child:( |+ c6 G7 A; i f4 X: Z4 `
child.parent=parent / L* h8 M3 ~$ [+ K1 s1 K8 ? if parent:$ ?! H% @7 N; E+ v9 P0 J& I
if parent.left==node: 1 b# r$ e+ f X9 i0 G parent.left=child+ d0 v9 C2 A' Q \$ L2 L
else: . a4 F5 {# h9 l- \9 r parent.right=child8 |, k- |3 V' Z0 r6 F6 }
else: 2 S3 h; r& L q- J% x L3 ^. b- ` self.root=child ' P+ q! A# K7 `" S0 b8 [# C+ J% L8 {' ^6 y5 T; B
if color==BLACK: 1 p# Y D' D" F+ W( `2 p$ @9 n. K' c# @. H4 ?
self.rb_erase_rebalance(child,parent) ! d% z! g- V- u4 ]/ q r) ?7 p 0 I4 z0 F9 @2 T2 S r) u7 R" X( G' j7 n1 e) X; x
def rb_travelse(self,node): + e3 G3 p1 ^ q% Q, o$ q4 s2 u if node is not None:1 Z/ x9 o# c6 t
print str(node.data)+'\t'+str(node.color) 6 y. `3 I6 E7 E7 ~8 d0 K9 I self.rb_travelse(node.left) / h5 u+ y a+ |. ]% s if node.parent: 3 b9 Z# V" j+ X, g( M if node.parent.color==0 and node.color==0: $ e/ ] l: {9 H) l, g4 d) i8 ]# ` print "error"8 w n( o% m8 F7 v" x
return; c2 \- b7 q: S& q
self.rb_travelse(node.right) % p+ |& W g ?( V2 _6 X3 Z- v if node.parent: 0 Z6 M/ R; W: I% ]4 C% x if node.parent.color==0 and node.color==0: 0 |" B- ?: ~: P) Q5 h, y print "error" 5 g9 b: N* f3 k" r0 H: h return ! i* y% i+ w/ L; E" E1 a3 |& S# [$ c# _! y
return7 b4 |. N1 D( A+ l5 F$ M
8 w, K& R" D ~% f ' h8 l$ j* R' m( d def cmp(self,node1,node2):8 ?) g, q& c- q6 C! S& q
if node1.data>node2.data : + y% V# N8 X/ u$ `/ l- v return 15 w4 O3 ]8 f% |9 o
if node1.data==node2.data :8 b( K3 _* g' z% _! D
return 0 2 d d U( u5 w7 g2 r0 } if node1.data<node2.data: ! b" F) \( E7 u. p: c8 O return -1 9 B9 Y# V+ B4 L* X # p6 z6 x* J6 O ~, oif __name__=="__main__": 4 O2 A" K5 p' |+ V8 Q1 @$ ~0 e print "main" ! E* {" {3 m: H) i' I data=[28,6,39,78,6,43,61,56,71,38] 2 S2 y1 j) g8 z4 |8 Q #for i in range(10): ! F- q3 h- c+ y Z3 w k8 G) N # rand_num = random.randint(0, 100)2 v+ N& ?! R9 z
# data.append(rand_num)5 p" Y6 I0 a+ [/ r1 L5 p
#print data+ K! a. j8 x9 o) X- `' N2 S! |
t=RBtree() 6 p" l a) B4 n$ J' I5 e. s# H; g1 Z- y5 h2 ]
- R3 R5 ~5 A a, n S' I5 @% n for i in range(10): 5 d9 W4 C) l( K. t, ]) ~" I& h t.rb_insert(data[i])$ w1 H- ` ]+ z2 W+ _5 z/ j& ~