^: g6 u! L6 aimport os U; C" N4 l8 F6 j2 o
import random ( b0 ]$ [+ k$ Z& \4 M, K9 a% w U$ h& }$ `) L2 L7 U4 y: _6 _
RED = 0 , L- U* u7 f7 s0 I7 W. L* ?BLACK = 13 K( Y7 y) x! K
/ b) N# E( h2 ~7 w
class Vector(object):' _% z: M3 z% q$ F) R4 |
def __init__(self,x=None,y=None): * b# z4 V2 ~+ D self.x=x! _) H+ T# j# h2 z! f- A
self.y=y 6 P+ D( F5 R* \) _4 ~0 w; w/ s: V & {5 i, m( r3 a) q: N3 Sclass Node(object): 8 ~# f' N8 m( x3 O """docstring for Node""" 9 d; x. |# b! X, g, i# m9 v0 D def __init__(self,data=None,color=RED,left=None,right=None,parent=None):9 d* y& u/ Y' Z5 \; A
self.data = data9 q/ ~) }+ |4 X0 U! d' s
self.color = color5 O$ ~1 w( I* o1 I+ k: c4 a
self.left = left' w% u) G7 }: x( [( A
self.right = right 4 {" V r5 c% |% M; v self.parent = parent9 y( i- X+ r U7 F) y/ W
( R- `8 k& f$ O9 X
class RBtree(object): ) A: u4 o. \# g def __init__(self): M* y0 }8 d$ y# r
self.root=None: d* @4 O Z5 {- r
self.size=0- ~) D" Z7 V+ z: f9 R, u. B
" | [4 K+ a+ S- q def rb_rotate_left(self,node): / {# b% n! n2 K right=node.right # W' h' `( R8 L: i. ]: r: p8 n& A z c- F+ c
node.right=right.left 6 z3 S# f8 h! e5 Q, Y# H if node.right is not None:7 v5 N2 `2 b, n" d
right.left.parent=node " H" k8 J3 P! z0 t* ]1 o6 s. _ a: a/ ~4 ^5 A9 x
right.left=node ( u) [0 l: i1 g. A J: ]- L6 l right.parent=node.parent; j6 {0 u- z( @ X% I" [; f8 Z( q7 s* x
G; K3 f: k% [8 D( e if right.parent is None:3 b0 g8 p, F7 N W3 F( S" t
) g, i- h) _0 c1 U
self.root=right * h# \, V( q2 E else:, a! f; C% e8 c
if node==node.parent.right:: c' Y7 G; h9 Z7 V; J1 ^! y+ i
node.parent.right=right , [( a) C( h- N) b/ m6 U5 S else:* Q' C- z m/ s/ J$ k# Z
node.parent.left=right ! e/ C M; N$ U; z node.parent =right) E S8 n6 C8 x( |( l' h
* G! n# \; o6 g! S- k# ?, i1 x1 e1 S' {+ x9 o% x+ I
def rb_rotate_right(self,node):/ `' E) t1 @9 ^8 Z9 V, `8 K6 f
left=node.left $ d7 R$ h" L6 `% D; Z) `4 u node.left=left.right1 n# R y' t4 O8 v
' F1 P7 {0 g0 I7 ]6 U" b+ C+ j if node.left is not None:% Z P6 }( n0 s# F; D9 Y
left.right.parent=node 4 D1 O4 _/ G; f" ~ ; Y' i+ a1 }7 s# l left.right=node % ]; n, O7 E( H9 E! t left.parent=node.parent6 A" b5 o2 ?6 A' B1 H5 O: [
" o* ^$ | H( K, @; n- @$ b if left.parent is None: 0 Z; p% a( N& v/ u) z) \ self.root=left ) F- v; E5 O7 p5 o else:$ \9 K- k& }& |1 J* z* P a8 [
if node==node.parent.right:; N7 E: Y) w! W$ [0 j
node.parent.right=left8 u0 _6 c5 u9 p* @4 R4 q. q
else: I4 o% j8 c2 q- O
node.parent.left=left* x1 X6 q6 D/ z4 U* Y! F
node.parent=left ( H' s6 Q/ U# d& g+ h$ j" [. |! f. ? L
def rb_insert_rebalance(self,node): ( @: h* @ M: ~; Z6 z. N7 H parent=node.parent1 ?' ?8 S" W/ `- @1 e$ T$ ^
while parent and parent.color==RED:2 d. H. r8 t, f* m n1 z
gparent = parent.parent' u& P0 \ S5 c
if parent==gparent.left: 3 c2 C* s/ z Q+ |4 w" Q% Q uncle=gparent.right % P! Z" |: ]: Z- ~: L) ~ c- x& e6 u) i if uncle and uncle.color==RED:" P, ^; B1 p3 p
uncle.color=BLACK+ l; @0 [$ b0 j2 \. t5 |
parent.color=BLACK7 I4 _0 z3 m- c! j# ^3 f
gparent.color=RED/ \" ~( N2 C! M# j3 W
node=gparent $ o8 ]/ U- S. `, s' }# } else:) y: O# u" s8 ]; [
if parent.right==node: ) o* t# t: B [0 R) p% f2 W) }0 u self.rb_rotate_left(parent) * f- K9 c* n! ]0 i8 } tmp=parent % _/ }% b$ `. U. V! H parent=node8 {% h2 X( `2 \# |6 G( w
node=tmp 7 b2 L4 C0 a' y' R& I parent.color=BLACK7 G! i* A' k& [2 {6 V- i/ T! G
gparent.color=RED : r/ P; O8 t5 i, a3 U8 l! {, @ ~6 C. V: E2 h/ ~8 S
self.rb_rotate_right(gparent) 5 x/ \( _5 f+ R2 E" ~3 R2 ?5 e' M9 I6 S3 B( G
if uncle: / G( E) Z1 j6 b if uncle.right:0 t8 j% {1 E; `) J; j
node=uncle.right ( ]5 p+ b! e% Z1 u3 e, i, j' ]6 O else:8 m" J0 z- o" g! H* n& Y
uncle=gparent.left 0 S+ j0 t0 t/ R" Z if uncle and uncle.color==RED:% d3 O l3 P& K/ J( I& `
uncle.color=BLACK # C1 Q# p( W- `& n) T' N parent.color=BLACK |, h$ T v8 k4 E, f
gparent.color=RED 1 h) \% s+ Z% i2 L, d: U node=gparent ' {6 m. u h; x) ^8 J, ]1 d# M else:/ L6 B+ i1 W: l) p% c: ~
if parent.left==node:: R& F: L' L, M( U
self.rb_rotate_right(parent)1 x: P6 e" l5 l* |, L$ [& |+ C$ p
tmp=parent 3 p/ O+ `8 n( b$ n' d8 @ parent=node ) N) |% w% V+ @ E4 @: k Y7 k" m node=tmp 6 F$ \' T: Y b N# O& i6 t parent.color=BLACK; t$ Q) g- v, U; e& s7 j
gparent.color=RED . f* v( z! _6 z1 Y5 n9 j self.rb_rotate_left(gparent): B/ x E; M3 W# P
# x6 j9 R, I U
if uncle: 7 ]6 U7 f5 ?: n if uncle.left:. M# d4 l$ B0 ]/ ~$ t0 ^
node=uncle.left 6 k9 ]* v4 L' v$ V parent=node.parent7 @& Q" d2 ]- ? f7 U- n& m: L
4 D6 z6 s" ]; Y# A# a2 { # x. S( _* D( B def rb_search_auxiliary(self,node):# V M. t2 r1 @2 |7 P8 Y
tmp=self.root( T. [- D3 j" Z7 A1 T1 @
parent=None* W. O# T+ g8 T. Y$ K
while tmp is not None: 4 e6 p, n' h. B8 M! q- X' s4 g' U" [9 w parent=tmp ' }- C# t. F4 Q5 B8 P9 G cmp=self.cmp(node,tmp)! o8 P# B9 K0 W+ c: J7 m! X
if cmp<0: C+ B7 `; O" l( z tmp=tmp.left! ? t& }, n. {
else: ) a6 W- l: [& ? if cmp>0: & _9 z0 t; L6 X tmp=tmp.right3 K4 S* Q( q1 t! a+ e. o0 E2 H
else:8 S% S: H' g2 G, a
return tmp,parent" O3 Q8 H$ V" y$ l
! G/ Y& G' L2 K0 @0 r% x return None,parent7 ?$ i# L! j& {) D- d* g
" P6 e. D. J6 o# G+ g! f4 J" h def rb_insert(self,data):8 i# }& J' j( N/ Z( c" l' E9 j, S# Y
tmp=None ; r& }, ` v/ A0 {5 y' @ node=Node(data) * S# s+ J3 G# Q3 Y$ l5 m0 v+ a tmp,parent=self.rb_search_auxiliary(node)( m9 ~" \% b \6 Y) X
, I; O1 V! e* `- p& R4 z7 N if tmp is not None:& N/ E E Z+ R) d# H
return 6 Q* ^ ~5 }% Q % `; c# _ B; ^6 y. ]5 [ node.parent =parent ! u+ L' s5 |% V" B5 ^ node.left=node.right=None 0 x/ A0 y# g# q$ ` node.color=RED $ U' q) r1 D, ^) C. v% C0 \( A! S" h5 N4 _2 v0 c/ w; D: j
if parent is not None:) m T# e5 g# O4 n! P
% }9 Q' o) [( c6 i
if self.cmp(parent,node)>0: : T5 u y2 C! L parent.left=node: H% \2 H, P% L- L Z
else: " x6 C1 V, x# B; i* F parent.right=node9 X3 y; {9 B, R% V) v( y
else: / J0 e9 C% l- p" F! t0 |. s/ m8 E self.root=node4 U7 s/ b! z2 y5 g
return self.rb_insert_rebalance(node) 7 O" ^" ~9 x( z9 q" ~ / n1 ]. e+ @ d. ? def rb_erase_rebalance(self,node,parent): 2 q+ Y! C3 |7 p4 ^ while((node is None or node.color==BLACK)and node !=self.root): 3 e. J4 Y4 [) ~! R& I/ e( Z' b if parent.left==node: : Z3 k7 S) d$ b other=parent.right 9 l) Q8 [* t: f" P& ~& \( A7 ~9 J if other.color==RED:2 c2 ]6 I( G. T% [3 Z* g# T9 M
other.color=BALCK6 K% j+ y3 g$ Z* H
parent.color=RED + `) ] l H4 y# E- n- o( c) u5 g self.rb_rotate_left(parent) $ L1 S* v( L2 n$ `* `4 a c! { other=parent.right ; }+ C; |8 a% v! r- d( n8 j) h if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color ==BLACK):8 m! p" G" y# y6 ]* w s, p
other.color=RED" F# P% Q F$ V* N7 ~' ^
node=parent C j3 E( `' j8 n6 L' h parent=node.parent+ t/ C- h. `3 y. R0 N
else:& j# N% |9 R N6 }$ M
if other.right is None or other.right.color==BLACK:2 t9 R& a4 ?# P. c
2 \' m: G; I% e/ P- x+ D if other.left is not None: + ?: K' E4 g/ ] v other.left.color=BLACK 6 s3 _* N) @9 Z) E! T. }% n other.color=RED8 {6 ?- v* @; y Y0 Z# M7 L
self.rb_rotate_right(other)7 |+ j3 A- ~- f7 k$ Y
other=parent.right # w5 L& s' B5 @ * f: D6 A8 \$ y1 N/ T8 t! W8 l& t G other.color=parent.color ) Q1 y3 F" U7 j% K& g parent.color=BLACK7 e2 b9 _' U3 i: L+ H) [/ x: ~
if other.right is not None:5 h% ?4 i: i8 i! ]. V: [
other.right.color=BLACK% K" c4 P! B. A" g2 ` i& [
self.rb_rotate_left(parent) * N# ?, A) S9 o; y! G node=self.root + `" ^4 f+ E5 I8 c$ n break * {6 _3 B3 I% g' V0 _3 s" l7 ~ else: 2 Q& g, T7 ?5 Q; ], T/ q other=parent.left 0 W$ P3 r: h+ Y* u) w+ P/ l9 M if other.color==RED: : w r! b& I+ Z$ l3 ? other.color=BLACK) m# H3 ~: c, P
parent.color=RED: F( i% F" k; C% X" r) s
self.rb_rotate_right(parent) " V3 L8 O! b! t- h other=parent.left 2 @$ i8 i. p; |# _) T l if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color==BLACK): ' j6 P2 x7 a3 q, ^4 ]9 |. t# M* r other.color=RED: B& [8 p' Y) p& t B* Z, b
node=parent 6 D b1 q% ]6 C, S& ? parent=node.parent " K1 S. g* c2 \0 a' l- Q else: * R A, [+ { C2 d if other.left is None or other.left.color==BLACK: . H' ~; v, i6 q1 I& i7 y' E2 e if other.right is not None: 1 p. W( I2 A% g: Y( ` _ other.right.color=BLACK' C! ~1 F9 d7 Q# j% u$ T
: E. K) r. O( }! D other.color=RED 0 W, _3 l* w" m self.rb_rotate_left(other) \, o# U) Y9 K N( \ other=parent.left ) p- F5 [1 j$ e5 @ % S* o; k7 v3 E- }! H$ { other.color=parent.color " @: C/ z' C3 N2 w4 ^8 ] parent.color=BLACK- J1 p5 F! L4 Z
|! Y% }# N: `4 a
if other.left is not None: $ _* r7 k& K. Z. |8 i, L other.left.color=BLACK 4 x ?7 q& y* c- U7 a; Z6 t: ]+ u5 L
self.rb_rotate_right(parent)8 J* Y; _: {. }# b
node=self.root, ]/ T9 O/ E# e# G) R& c9 G
break % C: O, p7 e& s$ c9 L/ W k! U. G1 H- z% Z6 O, Q
' y4 Y- `+ B: M3 `
0 V" f9 i5 q/ ]! u9 w) s if node is not None:4 s0 C8 m; T( ^6 n% Y6 d
node.color=BLACK / P; a1 x( L ]; `$ U" H % U7 w; P7 ~8 R def rb_erase(self,data):1 M! l3 T" K, d6 \, q) r
tmp_node=Node(data)$ _2 r6 `7 f/ H2 C( X
node,parent = self.rb_search_auxiliary(tmp_node) ( z( Z. K, o) m/ N" D" N1 ~4 s if node is None:6 y; H4 t ]2 F+ a6 a2 p' U
print "data is not exist." / a4 I/ G1 b% T/ {' b return% p1 z/ q( E, X/ G, _1 M
' ]% d% @ ?- c old =node. j# F, x+ }# f4 V
if node.left and node.right: 8 f2 |/ S) w" H% h w% F node=node.right# [+ m) Y/ C: r8 ]" ^
) Q1 _! P9 M, k
left=node.left ( }, k! b4 `5 _+ n! Z4 m while left is not None:# u: f, _. g5 d" M# M: L
node =left % _! v% V9 M, {8 F# g left=node.left p- z" ~' e1 G* ~
, C, ?8 [ R3 }6 C( M2 h
child=node.right ' v5 a# ?4 [/ B4 T parent=node.parent / m3 M6 q/ i. y color=node.color, Z# v% ?6 {* T- F) l
, ?! L' V2 Y+ B" m! D4 o- c
if child: 2 C9 a0 \" U+ `1 Q" _8 l child.parent=parent* f" J3 h8 M& k7 P$ \9 h1 L
if parent:$ H) h; x4 V6 U2 f
if parent.left==node: 0 t! c6 W6 g1 a; J' I parent.left=child( q( |+ D4 j* S
else: 5 D8 p2 u/ h, b8 I0 L/ O9 \ parent.right=child / m" |) C; ^& r4 ?* q5 `: w2 e9 i6 i4 r
else: 9 E; J N- _$ Q) g: g3 ? self.root=child8 ~* P$ f6 V4 L7 w1 u& g
, Z$ N1 X, b! i1 \8 B% W: x! q
if node.parent==old:/ p& ]' s8 L+ P/ h, s; E3 L
parent=node 8 z' @% G) n0 J6 x# p' ^ node.parent=old.parent; _( l: Z0 [8 t" c, O2 V
node.color=old.color 7 g8 T( R! ]3 X, D6 i node.right=old.right7 q% H1 D1 U* `* _% e
node.left=old.left/ D) n. j0 [! H! s8 A
$ `; s5 X6 @& E1 O6 f# b; u! q if old.parent:+ _4 M% B8 C8 Z
if old.parent.left==old: # ?/ P0 `1 T" G; p3 @ old.parent.left=node + I" [1 U( U0 _# R: B! H( y% q, x( c else:, A6 _% K% G9 J
old.parent.right=node4 L# F+ \7 }: f/ O
else:8 G" l- s, i" u! n2 \
self.root=node. x5 v ^3 M) o; q; k8 _+ q
' B$ M5 `4 j& f+ R2 l h old.left.parent=node ) u3 O. ~4 F/ i4 c if old.right: 5 t# k8 N" `7 u M" w old.right.parent=node4 _/ ~# \, d: Z: W/ v; N- u
; p' T& R9 R; R! ?4 I' g
else: " ~! p2 @' i2 x4 k if node.left is None: 4 {# E+ K5 o6 E& f0 p! g child =node.right6 o7 H' k1 K2 v( n7 v
else: . S1 h# G M; J. r* L if node.left is not None:5 C1 b4 K4 K" n& d R
child=node.left ! S. e' |# {6 o( l# [" A else:8 _/ }, B3 b5 i2 ?/ E* R3 F
child=None9 T2 ]8 i* o R+ F4 H' p. }
parent=node.parent " x2 E) `$ ^1 G) u4 ~) i. {/ ? color=node.color: t" `* q1 I7 I) U; _: F
if child: 1 `6 L5 _% v/ p- [/ C: J child.parent=parent, B+ I/ o" {* f0 T G2 u( N
if parent: & p" ]# o" @. |# E if parent.left==node:7 T3 T" X3 s6 ]4 v* p- p
parent.left=child+ r$ A8 c% x4 q1 I% ~: X: G
else:7 G7 F0 M( p: _ ~5 O5 Z
parent.right=child 4 E. [1 K$ @ S else:1 w' a# F6 B% L8 n% V$ K8 C
self.root=child 3 R2 H; \' B* f% S5 G; J+ o9 w n9 c
if color==BLACK:' ~$ W8 S- X/ t# b: H1 R
* f2 A! r+ r/ Z" n# V8 f, u I) P self.rb_erase_rebalance(child,parent)# S# `/ `. \) G: h
" _- r" E2 X& r" T7 Y : P4 Z$ C5 t( f" o def rb_travelse(self,node): - U. z+ J; @# w; a3 g2 N if node is not None: & K1 _4 Y% @7 u' x" I+ j- { print str(node.data)+'\t'+str(node.color) ) d( @) G3 l2 j self.rb_travelse(node.left) + x3 a% B) u( w7 M7 S! R2 e if node.parent:: J( ` [) b& @8 |2 N
if node.parent.color==0 and node.color==0: ) M t8 K/ ~+ Q( L print "error"4 b8 z; k4 N4 }" t' Q& j
return " @- h$ ] p1 [9 E self.rb_travelse(node.right) & P8 x1 I* J7 ]/ k if node.parent: 8 v; T ]" D, T" v if node.parent.color==0 and node.color==0: ; y* J! S! k2 A7 f( m print "error"" ?+ d& t2 h0 `+ F! {) @4 W* t4 {
return; T+ D0 _3 y4 v% }# i: N
- B) g9 r7 I) k D
return U) Z( Q& Z. B s
6 c$ J" H0 e1 b$ z. N ! [. U3 J. C; g- M def cmp(self,node1,node2): & J$ y3 T$ k+ ^5 B: m+ @% f+ w if node1.data>node2.data :/ E* x0 D7 Q$ C$ n; v+ u0 m7 N4 P. |2 o
return 1 9 R! O) b% e, y9 n6 b$ M if node1.data==node2.data : ' _% t9 ]6 D. k5 v- Q7 q, M return 02 m# h: m- V' M! J; y `9 o# d `
if node1.data<node2.data: ( z' d. R+ ^6 ~# i return -1( h! N+ y5 S9 V- B/ _( {/ X* _
/ j8 q! o. l$ b9 l3 Z1 g
if __name__=="__main__":( Q+ g; t; {1 g3 S0 f
print "main" + k2 @$ L7 W5 @& J/ ^8 g* `4 X data=[28,6,39,78,6,43,61,56,71,38]5 M- x3 M& E# O% S& W- s) S d
#for i in range(10):- k5 f) n6 r( Y2 P) [- s2 L+ ~
# rand_num = random.randint(0, 100) ! M( P& ^, K- F) T7 p0 m$ b8 j # data.append(rand_num) 5 F+ j0 g( \, C! c& N6 u& s #print data3 m* k/ W: }0 k5 S
t=RBtree()' @" k/ i4 g% x; }6 s! D8 `$ |
, J" R2 E- a3 ]
+ ?; l( N8 |8 a! r: v9 E; G7 d
for i in range(10):+ ?, z) r- X- t2 J
t.rb_insert(data[i]) 1 e; p" n$ {, x7 L& l8 q ]) e- b' Y5 g & B7 p( d% T$ G: v6 ~% d7 T# Y0 s1 H0 T! f' l
t.rb_travelse(t.root) e+ m `( I% w' Q/ M% ?+ f' _6 J4 V
% f, M5 Z. S- _& L
print "---------------------------------") R( V- D0 q. B
t.rb_erase(data[7]) $ l8 M( a+ n$ @. n' e $ L3 D& d! A+ E9 C9 L- h& `
t.rb_travelse(t.root); ], [% n. `9 F9 r8 s1 Z; N
* n% x- q; k" ]4 K; v/ @* d