1 D9 V1 {! h) Uclass Vector(object):' i: G0 n# @( i# E
def __init__(self,x=None,y=None): 2 K; a( | M0 l& o# j9 M# s; ? self.x=x 2 g$ h9 Z8 w. u( l! X6 y self.y=y* ], G4 x2 H0 o7 \" ?
) l% A- U" ~ l d0 L
class Node(object):# }( H( P7 c1 F9 A5 W( z% T
"""docstring for Node""" 1 C$ H& b; x( B: a B; ` def __init__(self,data=None,color=RED,left=None,right=None,parent=None):1 g5 O# A2 L; ]* D' L4 p
self.data = data" j- v- O& ?& H1 y% M* o
self.color = color 1 ?# q; ~& w& D4 {% i) } self.left = left % I/ j. C+ B9 p8 H# }/ j self.right = right! G s1 }7 F0 R+ Y
self.parent = parent, i9 \" d1 ?3 ]
( X8 N; B) E4 @* ~class RBtree(object):0 a! d8 w4 e v/ l
def __init__(self):$ e f0 \" E1 v% l$ I( z
self.root=None: |6 n& R2 a& l0 j B- g
self.size=02 a" i9 Z2 M. \7 x
3 h, w! h2 C, E" F3 a7 M* n def rb_rotate_left(self,node):/ K0 K/ F7 b4 @) e
right=node.right 9 h# l7 |+ I A1 _! ^' R; i# Y& g) L! H+ |
node.right=right.left5 P: _: N* L: Q
if node.right is not None: ' Z+ f, A* M$ d right.left.parent=node: F4 a: W# M+ g$ y0 @6 P0 \8 v
% l6 ^& D) E: p8 I. R right.left=node' n* g/ }! J5 M
right.parent=node.parent * ]2 \' v& S+ k& M" @4 e" V a9 C9 q+ ]8 G8 o4 a) e8 c( U
if right.parent is None:6 a! t6 B8 p& R# [
! M5 k3 d/ s1 R+ u5 j
self.root=right 2 R" G' K( r, f. z$ p% r else: + a- K: Y/ {% K7 g, g" Q if node==node.parent.right: / a( _5 g1 \, L2 K node.parent.right=right/ l2 }) e' Y# z% C; a! b& @
else:3 P8 g9 u* q3 R* m6 {
node.parent.left=right / l/ F* Y4 U- J' r# B node.parent =right7 |5 ~( _/ W, ~- o4 C2 v
# P" c* j; F) I/ C2 B8 R ) X A3 B- {. U def rb_rotate_right(self,node): 8 n8 x$ `9 f) T l$ i, X. k' m left=node.left( g8 @8 I! H. }7 s' K0 X3 _8 |6 x
node.left=left.right0 z+ z. X! ` g% Y; N
; b2 I+ U; B6 k2 H( d. c
if node.left is not None:4 U7 i" [2 K* _1 _# w
left.right.parent=node( I/ r9 P# v. v
0 i/ ]9 m4 b& ^9 A
left.right=node1 p+ W: R2 D7 c* Z' G
left.parent=node.parent* d4 L4 x' y' t' N" P5 w9 M* |6 x
! N. f4 I7 I& ]8 z1 T0 W
if left.parent is None: ( ^* c# \! ?/ Q3 c" w self.root=left+ o- ?2 z4 Z$ N1 r
else: # T9 ]) O9 P k) J3 p" L$ r if node==node.parent.right: 8 ?" b- j" i% G" T% b5 H! z/ `) C node.parent.right=left' M4 X9 c" H0 M
else:5 ]6 Y& T8 ?# O4 z, B% L$ g
node.parent.left=left6 K. I# Y+ q. o- E- p- ^ y8 P; P
node.parent=left 2 A6 ?- h7 {, c1 ~4 v0 s8 [& ? 4 F* @0 M& U* B0 z+ h' U0 r; a def rb_insert_rebalance(self,node):8 _# r# z& d7 K2 W
parent=node.parent 2 I1 l$ e& Q" z( x% d2 Y4 v2 @! g% L while parent and parent.color==RED: 5 O1 _5 A! N% c# [+ X3 E* _, U; e gparent = parent.parent" B2 S+ N6 ^# U: V
if parent==gparent.left: , @$ I; ^6 T' @- A, ?9 S3 Z uncle=gparent.right 5 C, l2 X2 O( H2 K5 F v1 s1 b if uncle and uncle.color==RED:' \5 W: h: a1 O. C [$ o
uncle.color=BLACK0 J: G8 D6 o# m% N8 Q" A5 x6 u0 L
parent.color=BLACK& H$ M1 h+ X2 [; {3 {, ^" H1 \
gparent.color=RED3 a5 \, x* i- U: \. u* s
node=gparent& v L# ^, ^% z: W0 H! Q
else:' t# ]4 ?8 P+ L4 |" d
if parent.right==node:+ R! q& b& n: E; L7 }6 S; v
self.rb_rotate_left(parent)2 i' Y M$ ?$ A9 c9 ?
tmp=parent" i) I o) s* t% z" C
parent=node k/ B, C" W0 b
node=tmp % ^# S" E: @3 ]- M% i parent.color=BLACK3 o4 Y$ e2 e) E4 }1 r$ {
gparent.color=RED ) R% u/ v8 ^1 s; \ ~5 ^: l( @0 }' z( N$ X- o
self.rb_rotate_right(gparent)5 q( h( n4 [0 C) H4 i
2 U( |2 c2 ]# ~# c9 d$ b. ^& c
if uncle: ' `' w! e. w, C if uncle.right: & H% \5 |7 k4 c- U: W node=uncle.right E0 o0 J; s/ S+ q
else:* A( @9 U. Q! {) U9 M* K* A
uncle=gparent.left 2 ]1 b+ |7 l/ A' }: g' a if uncle and uncle.color==RED: X, O/ [% N6 E; f! u+ s& d uncle.color=BLACK7 Z z; w5 Y# P4 m% K
parent.color=BLACK/ |3 g! A/ q) o( Q9 b
gparent.color=RED 2 p) h2 Z$ U- O. G3 m# l* g node=gparent) Q- g' |% {9 d1 Q& i# q; V. y! s
else: N' G( [1 o6 c+ r if parent.left==node:* L9 @0 q$ k& i, m& ^
self.rb_rotate_right(parent) 0 E" G& j, {0 s% f5 Y# _# A tmp=parent j J& J- f$ A, G0 G! s6 O0 v% \
parent=node / M ~; S9 I3 t node=tmp : o) O9 y+ v0 O parent.color=BLACK. `- X% }/ d2 W9 b$ M) d* ]
gparent.color=RED" n" _ h) K4 F. d
self.rb_rotate_left(gparent) 7 C9 {8 F7 v3 T) U& s% j$ d' N( ?3 Y7 X6 t
if uncle:1 ?% Q( D9 I8 v
if uncle.left:) t3 c+ ?4 B* _2 _0 G6 x
node=uncle.left ; W( F) a5 D! G parent=node.parent % e+ e$ m% o' Y# k/ I5 _' n" c4 m$ [8 E( d7 V4 M! h: `
! E' }( H; v1 I9 _# f( ]4 L self.root.color=BLACK: @+ s; X4 L& |1 R0 q7 ?
) J3 ]$ N& d( i. G4 Y4 L6 w
! R) v7 g+ r; }/ }2 J r% u* P, q def rb_search_auxiliary(self,node): 4 i8 @, `) P! j# v tmp=self.root7 `8 w* O; f, f" C: }
parent=None! j0 C2 s# u, Q+ i5 I4 T$ K6 C
while tmp is not None: 7 v- B4 Z& ^4 \' t parent=tmp 7 b) x" N; E, F2 k- o* c7 |/ l cmp=self.cmp(node,tmp)# [5 [8 Z& @/ W6 `
if cmp<0:5 ^! T! |! o1 w3 O" @+ V3 \% P; B
tmp=tmp.left8 E' W6 ]9 V; ]
else:( k; [/ V1 k) v, u. U0 l
if cmp>0:* h1 G1 r* c' c$ K6 h% `
tmp=tmp.right 8 z* T6 s) t1 v% S+ y else:/ Y' p# X) O8 g( w' ^! b
return tmp,parent4 Z$ v2 u- j* l, K) {9 c- Y, w
, P5 e; c% ?! B$ G return None,parent9 i, ~: b* X5 ^
" a: {0 G @* ^, ?; m4 s
def rb_insert(self,data):$ c3 |' y, j5 K2 A. ^
tmp=None " H4 X0 Z, O) T6 Z4 D8 | node=Node(data)% d; P1 m/ n2 u( l r3 _1 g
tmp,parent=self.rb_search_auxiliary(node)% M `* w. F" |
. K# J: z7 ^$ R# u7 G) v! A4 { if tmp is not None: ! v9 s7 ~! ?0 W& v2 c return " K& p& ^( U: T+ ^6 c: B! E# r" X
node.parent =parent, e' i( D1 T) k: m
node.left=node.right=None 2 e: {4 T0 n$ g% @* @, m node.color=RED- l1 H5 q! u) Q8 k& G
f% g# h% Z- I if parent is not None:6 e- h% B' q+ H1 i8 x% i$ O; c) z5 K3 b
. x4 J$ j2 w8 y
if self.cmp(parent,node)>0: o# a" @) ]! a0 r2 J+ [; [ parent.left=node7 h; v9 ]0 c0 Q4 D9 d3 Q
else: " `1 t5 H8 M% l' k parent.right=node / O) C+ t* k+ F+ C/ A) ? else: ( m3 {" ~0 T* a0 G, J1 P* w3 z self.root=node : [+ {# o+ q0 n- N1 d6 F return self.rb_insert_rebalance(node) " Q1 @$ `& Z. M2 L; S/ A9 g3 s& e; g0 P8 R1 V' x x* ?4 v
def rb_erase_rebalance(self,node,parent):4 v$ B" d# l3 f7 [
while((node is None or node.color==BLACK)and node !=self.root): ! A2 C; |, e) W9 } if parent.left==node:1 {, S0 ]% W/ W( `+ z7 c
other=parent.right2 g$ F5 D$ m9 J- o$ Z L" z
if other.color==RED: + z/ a6 A3 h1 y6 ~' A$ U8 s other.color=BALCK1 ~$ G4 o3 t$ O. }) T# W" i
parent.color=RED $ {; ]+ ^# m" M3 o7 D2 Y4 r self.rb_rotate_left(parent), A: |8 P- v" z4 i! K9 ?( k5 u
other=parent.right 7 i' l3 R, O/ [ if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color ==BLACK):2 i& E3 V O+ K- v+ w1 n
other.color=RED& C6 G: r; {& o+ T' v- n2 f0 q: N
node=parent + E8 U& ?% Z0 `0 j E @ parent=node.parent 6 `4 ~9 {, ?6 I0 U6 b else: ; E+ f) S/ i! R5 {. ?* F) V, Z6 \ if other.right is None or other.right.color==BLACK: * Z" x4 x, n/ R 9 C* x8 \) l4 d5 m' D if other.left is not None: : _2 ]& o' {, M( s+ u other.left.color=BLACK 5 t( k7 Q9 P+ a& ?- K( `, ?3 B other.color=RED 8 B4 E% p. K% d- @& N self.rb_rotate_right(other): i) j! f) g( P* ]5 Z5 I9 z
other=parent.right / k; T$ B; i* f2 c4 G' V) H: L5 R6 ^5 a( x
other.color=parent.color% R4 W! z" P5 k% p1 X& ?
parent.color=BLACK , U' l7 O/ C6 x ] if other.right is not None: Y3 T( R# y7 x9 R other.right.color=BLACK+ \: N% B1 h' B4 M d% ^8 j% a
self.rb_rotate_left(parent) $ ?' a( W, L5 {# R* H+ o, v2 J node=self.root 7 s& ~! x3 I2 }) ~ break " ?5 R% y1 L9 j7 _" K& G0 m else: : I* g& q* r; W& W! ~7 } other=parent.left - z. o) J6 P: ^6 U, L6 l if other.color==RED:8 n* B+ _: J) U; n8 R. f
other.color=BLACK5 j3 y; K- j W; L. ]
parent.color=RED . N! v7 }( r0 U" r( p9 O$ S! F9 y$ k self.rb_rotate_right(parent)- q% ?2 i7 P! _
other=parent.left 5 o( G6 C5 m3 q+ a if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color==BLACK): - u% v: ]2 ]' r8 o7 S- J, F' H% K other.color=RED' r3 o. b& V2 U; p. S
node=parent ( k2 {' R( f: |7 }" ` parent=node.parent& P' O- L6 z7 c) |
else: % D7 j6 y; H x3 Y- q* `. r$ \# M if other.left is None or other.left.color==BLACK: 0 N! ?$ Z. u6 l if other.right is not None: ) ~6 Y8 X$ l; t2 W: v other.right.color=BLACK ) \$ Z6 m2 m2 z! l: u1 v f# Y: z! N$ l8 \8 i I
other.color=RED. B# j: v4 H7 z6 H* b8 V/ }
self.rb_rotate_left(other) , d3 c4 f9 l% ^: ~* `( Q9 F' J other=parent.left) N1 J% Q3 z$ t: P
/ l1 L+ N7 ]) C. x2 Z" y2 x other.color=parent.color + ~' \8 D) z# }2 G0 J parent.color=BLACK , k9 c5 C# ]2 F ]( X1 u# ?. E q: M. P- k0 T
if other.left is not None:0 |2 b( b7 d( U7 S U/ T4 W
other.left.color=BLACK + m3 @3 a% v* o 1 S c- a8 `/ v* }( M self.rb_rotate_right(parent) " t2 w! x1 J. e& k node=self.root 9 s% Q4 x/ v D- ]; y break 7 e) @+ m7 ]8 v5 k# _+ F8 B) V1 f* J- [" h, J
$ O5 f$ C7 l" i8 K9 S
: E) v, R. J; `% I, v if node is not None: 1 h( F7 _6 i" K" {: k8 b+ \ node.color=BLACK 8 S W% f1 w" G( B q) w
' }8 H2 F8 ^ t7 U( e
def rb_erase(self,data): ' b: F7 W, D, ]. Q tmp_node=Node(data)& g3 J- [4 |/ c5 b: O
node,parent = self.rb_search_auxiliary(tmp_node) 5 Y* f2 O! I" T% e T if node is None: y3 E, h0 ~: f3 J4 P- E& J
print "data is not exist."+ Z& ~0 |! v1 O- B3 J( C
return$ d/ F8 E: h# c2 b8 z
3 a8 h' Z5 H2 p4 ^! i
old =node( V3 y# n, u% ~
if node.left and node.right:/ O8 a! q% U+ L* R& i$ J& t
node=node.right ( ]8 H6 u% G4 j1 S- Y( W% Z' _- ^6 k
left=node.left ! @" e$ p- q& V. ^& o1 I1 I' ` while left is not None:+ S( v$ ~* o% _0 z; i
node =left / A) Z. S" o3 U left=node.left 0 M9 Y* ^5 r( @" n% K7 s! {, H; D# k3 j$ P0 i" i( Z
child=node.right 9 {* c% s; J1 d* u+ F parent=node.parent5 ]0 u9 @3 b/ f3 y% c# k
color=node.color 1 P U6 @) i: J7 T % H% z! [. g3 t$ t9 A* w' P4 v if child: j+ w' c5 ^6 ^0 J
child.parent=parent r; m2 w) u2 y4 y( {& E8 A
if parent: % C' u G6 F! v4 | if parent.left==node:5 \) D& z: S" T& R% T* b+ `
parent.left=child3 C8 W& E/ J* m& I
else:4 l( B; v# i8 G3 T. Y2 [& f9 A& X
parent.right=child 3 j C0 |) K& Q: D& o 3 `8 P: o F5 w& V- J- X! D else: + w$ H! t! [: I: U: O& V* e self.root=child/ W- e6 @% N) f! c' B0 c& k) k
7 |6 S: M! P8 z D$ H if node.parent==old: , D, P1 L) S( y; t: Y/ |: [ parent=node % _! W' f% ^, Q% d node.parent=old.parent, c: ~! | P& X" Y6 W b4 C6 _( g4 W
node.color=old.color , Q& S% v* R: y" x1 I9 U p node.right=old.right' l. ~1 Q0 q/ e. ^3 ]5 p- w! f1 F+ \3 x2 N
node.left=old.left ) u2 t6 X% h8 R0 g$ Y2 N2 g0 N$ X2 v. A0 G6 W1 }/ r
if old.parent: ! W/ H: u& Z# v4 a if old.parent.left==old:. K4 G& L- ~# q. B; V% j& P
old.parent.left=node ( I4 U4 J+ b8 A4 R else: + X0 I& P x4 v b6 X" G b! j old.parent.right=node8 g+ j Y9 E5 u' R- C7 A6 J7 V M" f6 `$ J
else:. h4 G9 a, \+ r, p: ]
self.root=node, T6 o: `+ F) \" ~) p3 z# t7 f
7 V; @% L s# O# `* l
old.left.parent=node$ I u* X4 ~. q
if old.right: ( s7 I( G; y7 ^! `/ B old.right.parent=node 3 }. r, Y- y$ F7 d) t2 Y' p- L9 L7 Q3 q( K( D4 K" b7 H0 F
else: + L# t* O. S0 |( m: l if node.left is None:1 l* J# Q% A9 f/ j' T# J8 g
child =node.right & c$ z& K) ~+ C6 s else:8 s5 x" W7 r2 i7 q
if node.left is not None:' z6 O k2 g5 x, I
child=node.left, h ]$ V0 r8 S- b& m9 s
else: + E2 s$ [3 c8 C# B) c child=None# [! }% k9 R! Y% X" m& `0 n
parent=node.parent- \" ` c7 ~. A- O' x" E$ I" U
color=node.color% G9 o# W/ a7 L7 W
if child: & Y5 ~# E; ]$ ] O0 ^ a' o child.parent=parent+ H( S7 ?( K a) Z
if parent: & m8 X+ k2 w( @6 ? if parent.left==node:" I. n m6 H S5 e( s
parent.left=child$ g* R/ C2 V' W( B1 U
else:! _$ R7 r' n( F9 m5 I
parent.right=child: X C W5 |# b6 X& }# M% S% d
else:7 b9 H' s2 Z, Y
self.root=child 7 m2 \4 c+ x% Y# F1 G; `$ ~8 L9 \" ~. g( P6 E8 C
if color==BLACK: ) y9 t) Q; `" w " P$ Y( \ G, d P. z7 Y self.rb_erase_rebalance(child,parent)% }7 p; z4 B% b
! Z% K& ?$ M4 o4 Z1 @' o- x, Y+ Z, ~; O. o
def rb_travelse(self,node):; R/ f3 `4 `1 [ C
if node is not None: ' Y/ v( n. J5 Z t$ u print str(node.data)+'\t'+str(node.color) $ Y, y6 V+ e. R( N2 t self.rb_travelse(node.left)$ z* Y. U4 \7 W% O4 g9 u& d1 h
if node.parent:( M8 o& @0 g. R+ ^9 V
if node.parent.color==0 and node.color==0: ! r* s3 |9 Q* }0 Z print "error"" f! P5 j# u4 b7 n, o
return $ f/ k( t2 ~3 r self.rb_travelse(node.right) , B) ^" e& F$ W3 c" Y- z& } if node.parent: 7 K2 |& C% ?: p- g7 ^" ?8 J1 z if node.parent.color==0 and node.color==0: 2 Z; v; U* `+ G* O( d/ e9 v: F print "error"/ l, H) U8 r' s8 d) D
return2 Y% ?: v; ]% ]# Z, P! Q% O
& Q5 f( J E4 h& M6 i return' b9 y7 D9 G+ O, u$ j
5 m: O, I4 T. H I& {: j$ R
! Y* `$ k- D+ j" z2 R def cmp(self,node1,node2):0 w2 S/ R. P$ h/ k, I! K. H# X' `' l6 n
if node1.data>node2.data :" b* O& H3 T) n8 }9 ]
return 1 6 J2 R! p8 n3 f, b3 I if node1.data==node2.data : $ p& _/ m U" F1 P9 c5 s) M, w+ ?- {! M return 0 3 I( |; b u- P; S0 P" C0 O if node1.data<node2.data: ! Z& n* o2 }+ `1 r J return -1 4 I8 L0 G" f$ I9 t/ C: g ! h0 X& N# c) c0 w* H9 G. Yif __name__=="__main__":5 C" F* {: s! c
print "main"1 b4 ~/ X0 H4 i& k% L7 o8 q8 U/ S
data=[28,6,39,78,6,43,61,56,71,38] / ^7 |* Y0 j7 ^/ b8 g" E #for i in range(10): 9 g6 H% n! p) l) l' z # rand_num = random.randint(0, 100) j: B, `2 D* t8 f3 }
# data.append(rand_num) - f- m* Y4 y' W# M6 | #print data/ i7 g& V3 `0 j8 d
t=RBtree()2 n- T2 Q( O) }. U/ N- z/ q# B
! P/ `9 N, [3 D/ o6 f3 [; l5 u 5 t% R: m- i+ ^5 o for i in range(10):9 @# f2 h% {2 p5 p8 F
t.rb_insert(data[i])! O- ]3 g" `3 M3 L, w$ m
. N% W6 K" J! W: f, |' N/ F" ~ W/ {+ z* }. j2 A3 D% l: S- P
t.rb_travelse(t.root). I4 h4 m) U; G+ z5 j
8 W5 b/ F5 |- ~9 x" E; m
print "---------------------------------"- C9 s C2 \0 l8 f6 {) p$ @
t.rb_erase(data[7])3 L2 ?, v2 K, y! o v+ d8 m
4 h8 @- H4 Z/ x* s0 P2 D! r
t.rb_travelse(t.root)7 g% ]/ z- w6 h5 f) v% B/ H
0 d8 ]3 B1 n2 @* B9 ]0 `1 l q