" {, B2 P: R4 j6 h( }RED = 0 " ^: B& T1 Z8 ` n0 k. r5 F \BLACK = 15 d- S" p8 A; o9 u
8 U. C; q# ~( D$ J- kclass Vector(object): 8 S& v' @# E- e8 c/ X0 r6 b& \* S: w def __init__(self,x=None,y=None): 0 L# V5 _' _# s9 X R self.x=x / [5 k8 d( E3 `* L7 ^ K self.y=y1 H: f+ s5 T, G0 Q- l* A9 M) H( _
% D P9 w2 F6 u1 g7 M# b% vclass Node(object): l8 H7 s6 _ t2 |( K! U: i """docstring for Node""" : P8 T7 Y, B7 S& \2 z) } def __init__(self,data=None,color=RED,left=None,right=None,parent=None): . @6 c- K0 X5 S' M0 k& u5 i& m/ M self.data = data " w! [2 `8 Z5 W0 z* C" ] self.color = color 8 r @' L6 Z0 C, ^2 y* t" R self.left = left + Y7 ~- O* Z! \ self.right = right7 i4 @6 q, l( H% c7 N: y
self.parent = parent. a! t6 I- o0 F+ Q
; |1 B+ K. n s" k5 L+ cclass RBtree(object): ) X8 E7 H& E# A6 h! n def __init__(self):1 b5 ?& c- @# x$ G [! R
self.root=None ) R! ~6 d( {5 W9 O, W$ ` self.size=0: L; H% s( o) k2 |
! ?. c0 G8 m. J
def rb_rotate_left(self,node):1 f8 G$ Z* W0 q
right=node.right * F: B( ~% \; o 7 Z; ]1 [. O8 V. `; s node.right=right.left 6 C& p o& z, n ?3 E if node.right is not None:1 ~7 S- r! k+ @. w n% h
right.left.parent=node+ d. m" S7 ]8 q. f
2 K0 U( v" _- u0 L
right.left=node* o% l: D( r( l" g
right.parent=node.parent3 i0 @ a. H8 m7 r. S( n
5 H$ |( w. W/ R- Q
if right.parent is None:' `" B" W% d) B+ y
' L5 O# B$ F c6 O5 Q$ k
self.root=right# q$ I/ i4 Z+ h, K
else:7 C& S1 P8 {* f- A$ v% X/ l
if node==node.parent.right: ) Q5 ~! ]# o. z& {. n node.parent.right=right, N. P l: R9 I) L: f; \( w. j
else:/ n q r3 A3 k
node.parent.left=right2 c1 F4 F; k; I! p# l" H
node.parent =right 2 b1 c+ \) {7 c2 u- y& V$ K/ F Z3 J* H: E! W! I
4 v7 q6 C, E T4 e6 l5 R4 z def rb_rotate_right(self,node):0 c- f) e+ g2 f- m5 K
left=node.left: p# J# h1 d* U" Y/ W
node.left=left.right " J2 P7 B8 l7 I& V8 z3 {) x E1 T6 K% A. c; d
if node.left is not None:) v$ s) i9 |& v8 t5 W
left.right.parent=node / o; W* {3 f" w- u- N" Q7 R% o7 g% t . L' O3 A. ]( b left.right=node+ ^% L6 o0 q- ~
left.parent=node.parent1 z7 J) S& W" K) ?/ k
5 r9 n" S2 x# C0 A( I+ `3 ^
if left.parent is None: ( _! g4 u7 q- b+ S self.root=left8 l. s3 X" u# W6 P8 N( z
else:. w. [/ B* _' ^5 a& d, z
if node==node.parent.right: ! j6 l" b, H) _ node.parent.right=left ' Q* ^6 C. J! c l | else:- ~0 n$ P% R& o0 q# k2 ]7 }
node.parent.left=left 0 A$ O/ h0 q2 c- g8 \. X node.parent=left l3 e$ z& J, \: L7 N6 @0 h$ x4 x3 w* @5 G: t7 L3 S( N& X7 d
def rb_insert_rebalance(self,node): . A, l; \4 L- m" Q8 p parent=node.parent: W& T0 g- v | {8 c
while parent and parent.color==RED: , k9 u- G0 Z7 E; e gparent = parent.parent+ _* P" e* b# |" Q$ ?3 A3 ^4 }# e
if parent==gparent.left:+ P& {! T d8 f' ?2 o
uncle=gparent.right( P- M4 G) f4 D1 a
if uncle and uncle.color==RED: b: i. v; @# U& Y uncle.color=BLACK . H! J, g/ ?6 l9 h( R& F6 I parent.color=BLACK7 N! @; B- N5 R$ [8 F" n# b
gparent.color=RED; ^$ w7 b5 w: K U, e+ v
node=gparent , n% p9 w7 S% x) G else:' @# A! A$ I1 l4 M: X F
if parent.right==node: 1 p. P; _8 e! a+ j3 B# C# l self.rb_rotate_left(parent) + T8 p( S7 c2 c m tmp=parent . b: j' o, m" N, D* o G parent=node 5 u/ v6 y" p: s1 P( V7 T: ~2 a node=tmp : b1 r t9 Q. }1 n0 F parent.color=BLACK6 r. x" I/ u! o% n
gparent.color=RED 3 v, E/ M5 v- R 8 f. {% _, z6 b6 U- r, S. r. [ self.rb_rotate_right(gparent) : X0 `! T5 Z* J8 }/ r$ _) A/ v8 s * q A( U# ?- I: ^5 a4 O$ V- k if uncle:; S3 a7 d+ \. [0 D2 M
if uncle.right: - f' n- o+ u- B/ p; T node=uncle.right r; \- I) P) P: _! x- H0 I else:) ^! {, i) x, ?% l
uncle=gparent.left , i% A$ D- j6 d1 H$ _; L if uncle and uncle.color==RED: % u! h' j2 n9 L8 J$ T( B uncle.color=BLACK ' r7 e' O9 k( _8 I% r; e parent.color=BLACK; A2 W0 U( I6 T: n* K6 N; }
gparent.color=RED- o* G# {& U2 d+ ^0 u7 V
node=gparent4 A) n" m% ]: \* T
else: " o! T: C$ N* ? if parent.left==node:- d3 q S. a- B! g& J
self.rb_rotate_right(parent) ! }/ p S* G9 d x2 M; g. E6 e tmp=parent & Z' {5 _. x( ] parent=node $ _7 M1 H( k3 D; ?) `9 U node=tmp - g, K9 r) P( Y4 L! S# c8 s parent.color=BLACK* ~$ m% N( W, \7 Q0 _ ?* y, V
gparent.color=RED8 F4 r$ w! F" b: q1 \2 Z) e
self.rb_rotate_left(gparent), {- i) S7 P6 N% [+ F, b* q
8 m1 e; Q8 w& A o0 t% P9 }4 Y4 D" Q# B if uncle:. \1 W1 a8 M* i
if uncle.left: 0 s, h7 f3 K# t# Y' U node=uncle.left0 D7 E% y2 c+ b, t
parent=node.parent0 X$ G( q: n) y! V U# m5 e8 q
' G l' ?0 {( E3 J+ Y* h( w " K# w5 m6 H/ r self.root.color=BLACK 6 t+ q# e8 H2 I3 p6 k: P + s& A C7 F/ k/ o ' q/ F8 k. A U$ A% u) w' | def rb_search_auxiliary(self,node):2 @1 r: h9 L6 E7 _$ A( b
tmp=self.root; n! g4 C0 O! b, o
parent=None 3 d% y- C7 f/ k. T! e while tmp is not None:# g( V+ w l; \: n8 D
parent=tmp) I5 m4 U8 L! ?9 q
cmp=self.cmp(node,tmp) 6 n- \+ m5 F, B- M& I! h: j if cmp<0: 5 y8 L; _5 C2 z/ ]# _' V; P$ Z" V5 F tmp=tmp.left5 e& s, {; O" F) Z9 b
else: 8 T! T- Q# e0 v5 }! Z0 G( s# i if cmp>0:9 J5 p3 g6 F5 ~7 o, h- @
tmp=tmp.right * Z0 |; f& u5 c4 W) S0 S else:, O0 r9 W. W; E, b: p
return tmp,parent / [# d/ S/ }% _ ' O8 g. `" J3 i8 K0 m) s' c return None,parent9 U; ], @# h! U
3 q- _8 G; T4 D) z" k" Z def rb_insert(self,data): ; n0 y" U) G' ?# M tmp=None4 p6 b+ a! `3 ?& k! G; r6 W, D: E
node=Node(data)% B$ X6 J. N* t/ l" \
tmp,parent=self.rb_search_auxiliary(node); m" J( I& q3 }8 Q0 S5 p
6 R. j* ]: G7 c if tmp is not None:$ E" V, K) i M3 S& \& Q
return 9 m/ g4 M( Y5 D7 d, B; h
& N ~/ @2 w0 \8 [- x1 Z1 u
node.parent =parent0 t2 F2 u `0 N0 D8 y8 z- j
node.left=node.right=None 8 ?9 M6 M1 r! k' u node.color=RED6 _7 A! O9 n; r2 z
3 E& A3 W8 U8 e* ? if parent is not None:0 a, K7 w2 a, t* e6 L( F+ g# r' s
3 B7 J% O# {. D5 I! N$ P4 x/ e
if self.cmp(parent,node)>0: 7 |" U+ L; [3 [1 ?8 w' O parent.left=node9 Q) c6 `$ [( b3 h6 }/ s9 o7 i' B
else: 8 v+ K- ^: f8 \7 ^8 L( x parent.right=node, _- a b" ^- z$ }5 U3 o
else:" Q7 G7 _1 H, G: x4 Z+ C; t2 w
self.root=node ( E! \ X( r0 o return self.rb_insert_rebalance(node)% \6 v/ q9 I* p) _" I
1 ~- ?% l" D# h5 z
def rb_erase_rebalance(self,node,parent):9 d0 |; Y- t) T! t: I: t
while((node is None or node.color==BLACK)and node !=self.root): 2 e6 h" |) N* y1 n+ l if parent.left==node: 2 C, \4 ~. ^1 F" T other=parent.right # ^& n) r: {5 v _- C0 A3 \( n; U if other.color==RED:" E. m+ `& X6 y) V( T! T, S; A
other.color=BALCK" ^; X: Q5 S5 F* [1 a
parent.color=RED7 T' C3 s7 A4 v# d0 p# R
self.rb_rotate_left(parent) 2 @" d' Z* C, K1 S5 h' D5 W other=parent.right9 I a3 N1 W* D" T, l2 \
if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color ==BLACK): 1 O& Z* `" r& O5 y. E7 @. I other.color=RED 9 o1 H$ n% m4 v5 q3 V. m- I" ~ node=parent# j! M9 l7 G! u" ?, F3 e7 v x* R
parent=node.parent4 a" W/ m! r0 v3 C- y4 ^: e2 H
else:& {+ q' Z, a- \9 e; e; v, ?
if other.right is None or other.right.color==BLACK:9 p4 j% a& ]! | S3 J \ M
7 n1 D# W1 G( B5 t
if other.left is not None: 1 Y2 ~( r. T% x2 _8 O0 Q3 X& g other.left.color=BLACK, f5 m% w0 h: a% i- M6 K# X3 Q, Q
other.color=RED$ p, V+ B) @ [3 `! \
self.rb_rotate_right(other) 9 w. v7 J0 H% _! L) V" ?( n other=parent.right/ } P ^4 K8 U* E* ^( X% f
8 c6 l2 K7 E% ^. p4 V1 E, [ other.color=parent.color / Q0 G& C, H2 o6 i, t- \ parent.color=BLACK0 d5 P' Y8 W- |" [/ @7 c7 Z
if other.right is not None: - E9 ^0 U* K9 p, j/ O other.right.color=BLACK 6 x5 _- _+ e% x/ T# Y! m0 } self.rb_rotate_left(parent)0 P- q/ i- u' Q5 l2 Y: p
node=self.root + k0 o7 ]; V; T) s, X* r break, e1 Y" S6 C2 x% |. A
else: ' h* M8 r* C2 {4 p" p9 b7 Z; U2 p other=parent.left, ~/ ]2 r, o' W+ R
if other.color==RED:+ N$ i6 o" [- \6 ^! Z. s$ P% y* e0 ~
other.color=BLACK. u* l) w5 B* W+ L0 K
parent.color=RED - D# r) h4 Y% Y- I6 @6 A9 x self.rb_rotate_right(parent) + y) d1 T1 k5 w2 ^ other=parent.left& t* J$ Y2 `* |/ T5 z+ X$ h6 |( W
if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color==BLACK):/ n) E& t+ J: c' W( y9 w/ x) ^2 ~
other.color=RED2 K3 y& F- r' b' O
node=parent* I: a. Y1 {* ?- n- w- Z/ _: a# S+ [
parent=node.parent * b" `2 n7 a7 W9 {' @$ ]- ~) [ else: & F& N% [3 x8 Z8 M& I' x* q) ] if other.left is None or other.left.color==BLACK: 3 G7 C5 W( w4 I, {. S, k6 H" P8 X; A if other.right is not None: Y: c9 K& I. V3 e8 {
other.right.color=BLACK4 G1 C# G7 p a& } {
" o, f9 r" G Q7 T, Y1 }/ Z other.color=RED G& b# O. F$ j1 m/ X
self.rb_rotate_left(other)' z& _$ t6 V+ }! f( r4 ~3 f
other=parent.left# W3 { H( y/ D/ q
& E, \( v( G8 Y" ^* J k other.color=parent.color1 R5 e0 |) }# B3 z( M8 n
parent.color=BLACK) P1 \' V3 P r2 s6 }, \, ?- J1 Z
: n$ N6 [6 S- E' a if other.left is not None: I. z: D# U" [' E. l) d
other.left.color=BLACK 5 ?; E) a# V6 y e2 \3 J! \ ! Y' j7 L ]1 ^5 P self.rb_rotate_right(parent) 7 x# a8 h$ k/ c1 x3 x8 p# v% s node=self.root * e& V5 I4 J6 u# d$ @2 r break $ n8 V3 i% D! Y% T% ^7 V . Q5 l2 u/ H( y- g- K5 v( T2 @+ M. u7 N( q0 H: ^* }4 F/ |
' M4 b. B3 V- s4 r if node is not None:# v) z5 Y N7 s% O8 r7 L
node.color=BLACK # Q M9 G7 Z. E; o) |
2 ^! X, n; ~" I1 u% X
def rb_erase(self,data): + J0 @6 n2 L# W8 O3 v tmp_node=Node(data) - C9 i. U4 D- a/ U node,parent = self.rb_search_auxiliary(tmp_node) & J4 \! p- i0 ~$ z; S9 y) ] if node is None:" f! r' |% a5 L+ {% X
print "data is not exist." 2 H7 }( n3 i8 y7 P* A" }: F return8 X) Z6 m( @2 M6 y; G
" N6 `4 I* E! a* `# l old =node , X6 q N& x0 Y if node.left and node.right:8 @) a U2 J8 w. {& I
node=node.right 8 w5 z5 c3 |' ^* W" e: T( I - o7 j4 \: t1 V# y4 H; q- G H' A left=node.left ) N" C* M/ X3 | while left is not None:/ }5 `1 J2 ^1 y2 }" W
node =left9 A$ L* B7 s0 {8 q; r
left=node.left # c8 f( I7 |0 }! c4 Y. _* r8 ^. u! {! H5 v" P* y0 l: i) |4 P1 `6 s
child=node.right/ M" S5 i) G' i" t8 l$ |5 _" q
parent=node.parent w3 ~. `8 O8 j# l' J color=node.color7 {, n$ h/ Q% t3 I
2 ~: ]8 i t- [& B6 K) C$ F
if child: 3 ], i# d/ ~* s$ @+ [$ t child.parent=parent+ g4 N/ P$ }/ l, q0 e# m. x* [' H
if parent: 4 h: e' N8 Q+ [ O) E- {) d if parent.left==node: * I) O4 c3 q+ c" ^# } parent.left=child 3 p2 I2 S) l% y; w else:4 g( H# e$ v# _! e, {: A- W
parent.right=child6 a& i9 X( i* F0 c
% x7 Z: B5 w) ?2 S$ T( o" m
else: $ M4 a9 w8 X7 e S3 B/ n$ T self.root=child" o' G1 E+ R, P' _) X, o( z8 N
6 ], B; z+ O9 |9 x1 o if node.parent==old: , z/ b" j3 b' _. `0 t" ?- Q; l parent=node! Y$ V: ]4 E8 Y9 C5 n, v) U
node.parent=old.parent ' W4 b. }+ W) U/ D; ]9 O _1 v; n node.color=old.color ) b9 w& y! i+ O/ _; ] node.right=old.right" u" J' E5 J' `% u
node.left=old.left- ]6 Q# ]; G% n
2 b% p& P/ t9 T/ D
if old.parent: + X# N# W# s/ M8 j0 n9 T if old.parent.left==old:, x) I4 D# q z3 R
old.parent.left=node 0 ~4 Y9 B2 |% B5 m& ^ else: " X5 @0 S6 j9 z old.parent.right=node# q6 E( }/ ?( S' m$ P O
else:2 c' o1 j( r+ l. O
self.root=node 0 k+ }- L+ M1 m& i 0 c/ g3 Z$ l* |% A8 [ old.left.parent=node 2 {2 T. S5 g& _5 P( u: c if old.right: - T6 c5 }2 H/ `- U; d old.right.parent=node) Q9 j8 l* k1 {* u: A$ E& B
. `& s4 w8 |3 A4 C2 R; e& t$ |! L
else: 2 c1 b: w9 a' Q3 D: a# w if node.left is None: 1 m) J3 k C) N+ c0 c, k child =node.right & M |% P( |' l6 y* `2 y5 C else:; v8 ^( L7 [* l1 `
if node.left is not None: 1 D( h6 t2 N# L( Z. P+ ~ child=node.left4 F5 H8 e4 ^" o5 R6 Y
else: ' Y( P; ^3 S3 W3 w8 w child=None % N6 L( |) S& f3 P parent=node.parent$ s% p( X1 Q: {/ U. d3 F
color=node.color 5 H7 c5 u# H( b6 B# m) r if child:/ R1 q! z; Y) |# }" j* r$ }
child.parent=parent 8 ^$ `3 c) G, |6 Q# G. l' F. _9 x if parent:# o, V! @; V+ G( |
if parent.left==node:/ Z" y" y: [" _, v D( U
parent.left=child 5 X! r- j3 i6 l else: 4 m" p& M$ R- S parent.right=child% W6 x9 {9 B1 ~( r; p t
else: ; n' l" B# E* C8 m self.root=child 0 c2 L% N. L- _# r- q6 J' k: S5 o6 X$ W( e! m% }
if color==BLACK:4 \1 `7 \( X# p9 p& M: b5 S/ B
2 t$ L9 q, j/ i2 W self.rb_erase_rebalance(child,parent)% r" B- N/ u6 \' D5 \
1 R+ O4 T% l# K( W/ a! M* i 8 V2 ~7 P: o! Z# d# n) I9 U def rb_travelse(self,node): " `5 C/ x6 O& D- g9 X* q; P* v0 t if node is not None: ! @% ~& ?; h! l print str(node.data)+'\t'+str(node.color)8 L1 p# n- t# _0 P
self.rb_travelse(node.left) 9 |3 P) c+ `, S: H: M% p- y if node.parent: 8 A* [4 T' |" s8 |- Z if node.parent.color==0 and node.color==0:' R% t% {5 F/ U+ ~1 B
print "error" 1 s& [$ B3 u5 b: f' U9 m return2 L& b% |6 Y2 J
self.rb_travelse(node.right)$ A! N( |% I# n/ j
if node.parent: ( ]; ? a3 J# t0 ] if node.parent.color==0 and node.color==0:2 S" k4 r4 i/ p. p$ E
print "error"( C' S+ G& d8 o2 `* C
return 5 N9 n0 H2 K7 Z" @2 N+ Y6 X7 D( m: c' G L' Z" l. O0 S$ A& S
return 1 O* |2 c7 w" Y a + t$ y' l- F! a9 e% X4 B
4 q4 _6 W& A6 ^1 ^: Z/ s
def cmp(self,node1,node2):4 ?2 p2 `' K3 N
if node1.data>node2.data : 4 U5 q( r7 |, y return 1/ Y x3 `4 L. n3 q
if node1.data==node2.data :* c: m3 I% l( G- G6 B! H$ \
return 0 , K7 T; j- W& } J; m) Q4 w4 B if node1.data<node2.data: : z! }& G7 X+ K0 O4 Z8 z H return -1 3 b2 O' v' C9 R" W/ \6 g5 M% P! d+ b# g/ @ u" R- ~
if __name__=="__main__":. }! W, [6 Z/ a- k
print "main" * \: S( B6 u) `9 _5 u data=[28,6,39,78,6,43,61,56,71,38], w- b E% V+ A8 q; o9 T0 Y, V
#for i in range(10):: C4 z/ ~, M* e `6 N- l
# rand_num = random.randint(0, 100)2 x$ ]" n" u1 G9 J5 z. H" _# o
# data.append(rand_num) " g" r8 X. u/ Y( a/ s: x2 ^ #print data 1 w' C8 T2 c9 C7 d) Z, I t=RBtree() 3 ^5 M3 R, ~! h) k+ }& ^ . h0 b, f) i( k4 G [5 H( o6 v( _8 I9 |+ y
for i in range(10):/ Q: [! w: H6 `- u6 X4 C
t.rb_insert(data[i])- ?* i- b: D$ c; c+ o/ D
, e3 ]; E J3 @3 }5 v. z$ v9 N( Y% k8 M
t.rb_travelse(t.root) / t# n/ R; M' b9 ]5 {2 m" @ 5 l3 G4 @ C: ^2 u* r print "---------------------------------" $ F. B- }# B9 n! h t.rb_erase(data[7])& \& S; a+ `& ^, D