#!/usr/bin/env python . q. }, ?1 {; D( K! B# -*- coding : utf-8 -*- # r# K0 { r2 J! G 4 E1 N1 M* [: O" _$ Jimport os - J4 L0 ~0 O& l3 b. dimport random* |- |6 \+ X9 ~
+ T( e/ X+ s# J$ V
RED = 0& I# G( u) c8 n2 q7 S+ e
BLACK = 1 3 O0 N7 k( E. A4 K2 r+ ?0 X * m9 X; ?1 g$ e) f4 P1 v# j: y' Hclass Vector(object):; t; T6 Q/ x, E5 i, P
def __init__(self,x=None,y=None): 9 m# F, q6 D: \# j: u: v6 E self.x=x " i7 f9 r5 o" s self.y=y8 v' A2 D( J0 I
# f0 c( G& ^) E% r0 q1 l/ Iclass Node(object):2 Z0 j( Y5 i8 ^# l! P
"""docstring for Node"""# A' A4 S# u4 k* P' s
def __init__(self,data=None,color=RED,left=None,right=None,parent=None): ; U+ M: X0 z3 h+ u1 E. r; n1 c/ F self.data = data( H5 `$ a) s1 G& w" Z4 @; ?7 [6 k
self.color = color2 j7 R6 Z3 X6 n- }- k
self.left = left 2 w+ O4 S) e# z, v/ z self.right = right: j$ F4 {8 i) `2 k& {
self.parent = parent+ r' T. A( c: |! K. i5 {- O2 Q4 g
2 g, j% ]/ c# z
class RBtree(object):' b' K: P/ _: r) r; z7 s, J
def __init__(self):1 h& i& F$ \5 [8 u
self.root=None' a; J( X5 k$ @0 S
self.size=09 s/ \8 c% s5 G' W& U1 j3 w t# O1 k
; `* ]7 I: \; [( M; g
def rb_rotate_left(self,node): 1 }) y, S6 \2 u' I7 a$ ]" C right=node.right9 [5 ]' I0 Y2 S' R% ~( R
5 _3 q9 P, M0 F; y% A. |" ]
node.right=right.left/ ~6 |0 y, _4 ^
if node.right is not None:0 o, L" ]: k! G, N" d
right.left.parent=node* I, m& M( V4 L& k' e$ P+ f
1 _. w- l" X. ~; j
right.left=node6 F" ^4 Q6 @; L' m
right.parent=node.parent2 L6 K' ?, W( v
' N3 U+ T) s! z, H/ U* G6 d) N' g
if right.parent is None: - h5 g; m& J7 ]8 V/ F( F+ A , |. W' p2 M$ C5 m; a) p self.root=right 7 i4 N! V' S$ L, \* _7 t; c else: 2 x' b( \3 j6 V3 ~0 Q4 p2 h7 Y if node==node.parent.right: " \% w) e4 x( B. g( ]' B% ? node.parent.right=right1 b3 Q1 E, O. y' K' v6 n
else: & E% j4 |. I( g& O3 ~; @* b6 g1 f9 ]3 | node.parent.left=right) }7 t. I, `9 Z8 [4 L
node.parent =right; r8 A+ R1 }6 [
+ d: T; B" L4 _1 P. Q0 ^/ j4 \# e
def rb_rotate_right(self,node): ! x2 S& d2 U1 v$ j3 U/ o left=node.left ( V9 A7 H$ I/ l- h, Y9 m node.left=left.right ) x) u {8 W# r+ x0 f- |- a2 K# M5 s* R5 ^1 J
if node.left is not None:$ f9 W, \( g( p, n) g( U
left.right.parent=node# {; v3 n$ N# Z8 q. H f
8 ^6 k( I3 K- g left.right=node% I2 I& S) y7 v) A E! T1 @! i4 H
left.parent=node.parent * `0 A* p: Y7 {, T4 q" Y8 i + s& w0 Y7 h7 t3 }1 } if left.parent is None:, X0 k% a/ Q! X8 [
self.root=left* G5 Q% d0 W( s: z
else: + J! E9 C1 z7 t if node==node.parent.right: 3 B( ^+ C# ~, N3 C& c. D1 p node.parent.right=left ! H8 w0 R2 ]! d( @+ j2 G else: 8 C- _ s& ]. O# F$ d6 \4 P node.parent.left=left 7 Z# M9 z) T Q7 Z/ d6 P# L. e node.parent=left7 F. n" p; k0 e) T
, J& z$ }" Z/ V def rb_insert_rebalance(self,node):% N5 `! O2 _6 Q+ T& e7 V/ E/ g! }
parent=node.parent6 F3 U! R" i# T7 o/ A0 ?
while parent and parent.color==RED: & E, L6 a* i. `% ~ gparent = parent.parent ! u2 d0 [5 V+ G6 f: |( ? if parent==gparent.left:. X& R/ W& E4 R; Z4 r8 {0 Z0 m
uncle=gparent.right N4 d2 J; f3 z# I
if uncle and uncle.color==RED: $ b. O5 i l5 U3 O uncle.color=BLACK Y4 Y8 C) o8 z) s$ g9 M4 \
parent.color=BLACK * p% |: P& q8 X% m+ ~' k gparent.color=RED: L) d- g; ?% R+ G0 \4 Q. F; {) s
node=gparent + `6 U. k ]) Q+ {1 g" @* a8 u) l" ` else: x9 Y" \3 t) k% o$ M! c. M6 v
if parent.right==node: ) f0 m7 r8 ~( G7 f# \8 T: r$ p self.rb_rotate_left(parent) 6 ~ J9 g; g1 w8 ]; z! B tmp=parent / J- p7 y" F4 Q/ K" i$ u0 w. z parent=node9 T2 b, D+ G' B
node=tmp 7 ~, Y. s3 {6 h parent.color=BLACK! B8 `: w+ k2 h S" {
gparent.color=RED1 q5 K" Y$ t' Z$ |4 y, k* J) c
: c+ E/ Q$ o5 @
self.rb_rotate_right(gparent)9 e/ w5 H- m% T: ^
0 R# x- T) ~# x: O$ G& h
if uncle:9 G. y* |) h, |6 F4 N! Y1 b
if uncle.right: * i( p% Z( h( j. T( W node=uncle.right u! d* l* L. e% R$ ~
else:* E) \2 C" j% K" o( t
uncle=gparent.left $ }$ ]8 w- h5 f if uncle and uncle.color==RED:: z# {) ~" P9 P4 H- d1 A' I
uncle.color=BLACK , t9 s4 W& E. H7 x A/ ] parent.color=BLACK 2 C5 @- z' c4 a# G1 d# _ gparent.color=RED ) c& M% c( {1 V- v node=gparent% y! q3 F" \. k8 G8 I
else:6 C C0 ]5 k$ n( Y) k
if parent.left==node: % b5 W, o) k) `$ }( ^5 w self.rb_rotate_right(parent)- o% _0 N" |. ~ y
tmp=parent & _9 r1 P" y) C1 w1 ~ parent=node % b- d6 Z) e0 ~7 y4 v# e node=tmp / r- X; D/ c/ _ parent.color=BLACK' \* n/ T* C% ^9 _8 m4 c
gparent.color=RED7 e+ [( Y$ ^+ D
self.rb_rotate_left(gparent) ; R' L, t% l1 [, X* O( A* m7 q$ ?) ^ 4 M4 N+ r/ {; P1 Q) X" I- t" a if uncle:9 z4 d8 l! O$ m4 N5 K5 l' Y
if uncle.left:/ V, y$ h2 l2 v4 t* J
node=uncle.left/ o, e5 l5 }! f( B
parent=node.parent - @5 J$ s. ~# x; [1 q+ ]1 b2 S, o& O! d* H ( x' u0 W0 e# X 9 q, f0 O: I) F2 o1 e self.root.color=BLACK$ _) W8 c2 J! A3 `2 l# R, C
# X \, g5 { T+ i. i
! Y* X7 @9 H! ]5 o def rb_search_auxiliary(self,node): - @4 {+ V c1 `8 Y7 E- v tmp=self.root / V- s, e2 K# j0 B j5 ~ parent=None2 T$ A, _9 }5 y! E- G
while tmp is not None:3 \3 q7 A9 H2 N
parent=tmp 1 \+ c/ d8 f. P( m* `2 S# K cmp=self.cmp(node,tmp) " R' y1 Q I1 ^1 B; z; Y& h if cmp<0: , c% l7 T) h, m) ?6 w; x tmp=tmp.left 8 N" m" o+ ]% ` else: 3 K! S! X: B, R R if cmp>0:( i- C( [4 H( R7 \# J) Y
tmp=tmp.right ( ?6 }7 Q- I- f& C7 A3 F6 g else:, b/ c) Q% C: t; C, R
return tmp,parent . z' e3 [/ q& v0 a5 [. | 5 h. Q I7 T) X! n0 n return None,parent , k6 S8 i [9 U) P" Z9 v h. I& w/ Y1 [" f, x! F/ l4 |
def rb_insert(self,data): 6 d! |8 w% M, s+ S tmp=None ' y6 s1 l3 P& r6 | node=Node(data)( M5 G4 @1 f6 L: S% [
tmp,parent=self.rb_search_auxiliary(node)+ a5 d6 h# H" I9 ?/ `1 Q
" h: y. c5 E- m) _- N
if tmp is not None:* v& v- p! P0 D' I4 @" u
return " F7 G2 n# |8 P7 J4 s
w8 d) h+ u2 T8 ^, x* I node.parent =parent $ ?4 j3 w. B! a! c: ^ node.left=node.right=None 4 z/ _3 ?+ e5 T& }- p1 u9 ] node.color=RED$ B1 I L3 N* v8 m( T+ a" }
! u6 s8 a' j: _ if parent is not None:8 |0 y! ~ [ t) Y& q0 J9 a
}& [6 Y7 {5 f' I$ N$ g* Z
if self.cmp(parent,node)>0: + q% H, U0 f$ `; e$ B8 e- D. P parent.left=node ' r& ^3 p3 Y' K) h" b else:+ b5 i# E2 a1 c- E( x8 Y9 O! }' H
parent.right=node6 V8 x$ H: m! I6 T$ w8 G& c0 W
else: 1 L% c: M( X2 i" } self.root=node% s* o) A( r, }
return self.rb_insert_rebalance(node)1 U: c. f J1 i& X
2 r+ C. k+ o/ k3 p4 i
def rb_erase_rebalance(self,node,parent):1 L1 ^' E9 M( G1 g$ @
while((node is None or node.color==BLACK)and node !=self.root):8 |$ e8 B" @2 G7 R4 ~" g' W, z% l
if parent.left==node: % j" `) J. c7 @1 q% h' J& L other=parent.right / V, ?8 X( P. m7 {$ N3 B if other.color==RED:* f, a8 o2 d. R% {
other.color=BALCK 7 M* V Y: K/ d2 [5 q$ {6 R parent.color=RED2 G v) \& c3 g- z3 G/ z, D
self.rb_rotate_left(parent) 8 `0 Y$ Z, n, u' K' b3 F other=parent.right3 u/ U5 ?* ]# o- }5 o) Q! A
if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color ==BLACK):* H. ]7 Y0 p. O( m% M8 u+ s
other.color=RED + j3 ^# v1 ]( K0 @ node=parent * q) f& A9 l( t5 o8 R% t+ r parent=node.parent0 C8 L& O' ?- r5 Q
else:4 b& @1 P( D) x4 z0 z: Z
if other.right is None or other.right.color==BLACK: + @+ Y9 C0 {! a [8 u* M+ [ * F/ q- N, j' r' l9 f# g0 f if other.left is not None: 2 s+ n* R# D# N) y' J9 l! [+ @ other.left.color=BLACK! K4 q! P7 g( Z' Q2 W; _% x% M0 |
other.color=RED4 _* ]+ u% K- m
self.rb_rotate_right(other) 8 i; P. x) r6 p( }5 k$ u, l other=parent.right . j% H+ c* Q8 d & B9 j5 R. e8 W \: g' i other.color=parent.color / q8 T% u# ~& B7 A parent.color=BLACK % I0 H& J9 m: y if other.right is not None: : y4 s; D+ Q% Q2 C4 w" W other.right.color=BLACK* b/ V% M' B* c
self.rb_rotate_left(parent) 1 m6 Z+ Q" W) s x0 v node=self.root; K/ H9 C- s( u. W9 x% ^
break9 h7 i# s( I3 V0 Y+ q! o1 Q; `
else:- w0 d9 F. V+ q" X, U4 W
other=parent.left & u. I3 L6 M0 O3 A% d9 l4 r if other.color==RED: ! {" e& m& C: N# m# g other.color=BLACK$ \# ?3 P8 U" a7 t w$ X
parent.color=RED' z3 i% r% S" L0 _
self.rb_rotate_right(parent)$ \ p# e: Z- _& ]
other=parent.left9 [- c# b! h' X' O5 V( C. e
if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color==BLACK): @7 n/ E: U* e! @5 Q1 k' y
other.color=RED9 U) ^' Q/ I. I
node=parent ! D, e# `* {' @7 A- H9 c5 I3 I parent=node.parent $ `& w: w- g/ U' d0 D else:7 u) \+ X5 K) S8 F' f: ~' W( b
if other.left is None or other.left.color==BLACK:5 h9 ` S. c9 h. k O
if other.right is not None:. `" o( g4 Y: s) S( l
other.right.color=BLACK 9 O4 R) t p1 v) H' `0 q- ` t/ K- ~& ^
other.color=RED . o: a* q3 S( T% M# U6 R; V) X self.rb_rotate_left(other)3 R0 a8 n7 W, [8 I' ^2 A
other=parent.left E- e' U Z1 h0 H
& X( u. f6 z# H/ E
other.color=parent.color ! N9 K) P: v4 h) t parent.color=BLACK( |% {) B- K6 w/ @: d' a
1 P& d' A, e6 H7 U3 H
if other.left is not None: : u% V" \) K* T/ ` x; U! Z+ w other.left.color=BLACK ' c. S. j8 E' _: W& m- q8 m* r0 H( f [( l3 V$ \
self.rb_rotate_right(parent)7 r- Q" J. z) o% {- M, r: M
node=self.root9 i Y# b# h& t% J0 M) J3 {
break ' l8 j& K3 B% C, X# X/ \2 P5 C8 Q" z' k8 t) I2 P0 {3 Q. ?
; b. X( F7 }( \+ k% S- ~4 J # ?( u/ @9 n8 l: J! {0 u if node is not None: , E) i9 j% y$ d$ V5 p node.color=BLACK 1 b4 H; U, d4 d4 q & x2 m1 L4 k: q( c5 H' b! E def rb_erase(self,data): ) s4 J7 H% Y+ M1 s tmp_node=Node(data) 6 u7 d, w3 h) X node,parent = self.rb_search_auxiliary(tmp_node) % C+ u, I6 X3 l" j, g( E if node is None:! V7 I9 Y' r- N7 K
print "data is not exist." 2 |5 `9 E- |, m4 i: R& v return8 d4 x& r/ i; N. i+ `7 M* E
. L& h% ~% w" N4 I f8 k- o" R3 G
old =node ! q1 r0 d1 d6 e) B; s if node.left and node.right: x4 G: m! P' _: L3 }# O3 x node=node.right % @ `0 T+ V, T. ^( f * m- G; f/ ?9 P" i- P7 l left=node.left 3 U3 D3 \8 Z7 z8 f: P+ l while left is not None:$ r5 p3 f! D5 S
node =left! r( Z$ F& Q' N
left=node.left. N/ |$ j5 k4 M
% C2 y2 v8 [, L7 Y/ Z6 J/ Q
child=node.right# i* p3 l* E* S5 D Z4 L. F- ]2 S3 w4 M
parent=node.parent # B% v+ U9 S$ ~' Y7 p color=node.color6 R5 G4 C/ [# ~% A% B, I7 V
( o7 A7 O- t/ T: @6 Z5 O1 ^. A if child: 3 w- e- U) L! l2 z# I child.parent=parent ! g9 N6 o- g3 e: a if parent:* c7 ]! n4 X7 _, f+ Q: [7 z
if parent.left==node:6 y5 j# a4 e- ?4 z* `" m- y2 J
parent.left=child6 V" m0 K9 n( j$ h1 j8 z `
else:7 S( ^9 P& r! I! L" p, a
parent.right=child8 ?& p- z2 G8 u
4 g' B s4 j" B else: ' `8 A% j# t' A' g! n self.root=child( n3 F5 V" ]" C. M, `/ l
. Q$ m( z H& f% v* m if node.parent==old:. n; d1 H, S6 Y( x( ~. b/ \
parent=node 5 I# r8 v( b9 y5 }% B. T3 Z" _9 R node.parent=old.parent1 P6 M7 p) N) R& X$ p( F) X- B5 A
node.color=old.color . D( C2 t; k/ P& r6 Z node.right=old.right5 ]! d# t' U2 l/ E
node.left=old.left' O1 o8 H0 T( Y4 P) k" l% X9 i
( r/ y4 v( Y4 r$ } if old.parent:5 m! o! {3 |( v
if old.parent.left==old: - S1 Y: n0 _+ ~8 Y9 p5 R+ } old.parent.left=node 7 W" `6 m& @0 ?+ d else: & F. T/ ~& |; S. ]$ G9 L2 P( C) A old.parent.right=node" |4 _' p1 S9 ?! t" D+ v
else:3 B' y4 T3 r" V4 v, i M; s
self.root=node * `% M6 T+ s# c, L9 W ) z8 w2 ^8 ~1 v( m. L* F# p u" B old.left.parent=node4 Z0 z9 U( N' v y
if old.right: " H; S4 C+ w; a t( e) e old.right.parent=node9 f7 U7 Y n! C( P. r* `
8 s' P0 z9 I7 c# g! G' \
else: & @' |" O5 {3 S. } if node.left is None:0 }+ S' I6 I. l& s% U/ c
child =node.right6 I9 X9 a: w8 J" B" r) b) a
else:" v3 Y! ]- R1 @% @$ T: R
if node.left is not None: # E3 B( X( N2 I) A child=node.left ' j4 \2 H4 C; G( z% e else:* K7 t5 m& s2 n7 V; b7 d' Y
child=None * x( z! E7 U5 f8 C2 Q: f& o parent=node.parent1 l0 h# V3 N _+ v! t
color=node.color( u+ V- l7 `7 M+ q- r [- N& V* p
if child:4 v& t- T$ s) d; z
child.parent=parent 8 V6 e, b! ~- g% V g5 h8 r* w) Y( m if parent: 8 @, H5 z. n. j if parent.left==node: X) k- @! n& [3 Z: i
parent.left=child 1 X9 y4 u" K* o" p( r else: + n4 G" g4 U l ]5 R) O' A parent.right=child+ h) o5 y/ A9 Q" [$ }% j/ V& _
else:# ?# }4 y5 Z3 H& V2 t3 U' T# D' k2 P; A
self.root=child " Z/ N* J7 B( c; c8 A2 d) f1 z & j0 h9 V3 m! _* j+ f if color==BLACK: 3 a0 o& U* `1 Q. [4 Q& R- D/ o + F. D* v x' n6 j7 g' ?! U- N& } self.rb_erase_rebalance(child,parent)4 X' [. h7 j4 K% N7 M: Z- a
& a. G5 d6 v$ w' F
$ ?* Y, w/ |. o def rb_travelse(self,node): ) \" I( K8 G$ B( W# ^ if node is not None: ! K1 }# O- \& a3 m: s print str(node.data)+'\t'+str(node.color) L% W- h) c: Q
self.rb_travelse(node.left), X" G* k& X! T( g1 p
if node.parent:* ` F# ^' k, W" r9 L" g# n* e
if node.parent.color==0 and node.color==0:0 r4 s) @* H6 w
print "error"$ f- m4 v) l' D+ u
return# Q0 i6 G& l% d1 p
self.rb_travelse(node.right) & y, b$ X$ K0 Y3 ]- _9 n if node.parent:4 }0 j d* }9 N
if node.parent.color==0 and node.color==0:; _) ?* \+ D5 q! d% G8 R0 o
print "error" " L' {$ d! n# ]5 Q1 C return4 I& ~! X: _0 ]
+ j- O) i( z! v0 _0 Y( r; \9 [ return $ f( p4 a$ V- y. m$ d1 }7 u 5 n0 g1 o9 W3 [! O0 w i 4 B. g3 T Z; q) ], w& s def cmp(self,node1,node2):" ^0 G2 c, R- [# R1 r) k. u
if node1.data>node2.data : ) f- ?7 o% E$ g return 10 T- z! |7 x! d
if node1.data==node2.data : 8 h. d, ^) n) {% r return 0 ; ~, d' `9 ^2 N# ]0 }3 U/ I if node1.data<node2.data:4 A9 E* j/ X' w0 c8 w- d
return -1 ! Q6 w4 e7 `3 L4 O" A' G/ E) I9 V" e# U0 |
if __name__=="__main__": ) V: c. c- \; D- N ~# A9 J6 `* ~ print "main"' q V7 f% p* c, Z
data=[28,6,39,78,6,43,61,56,71,38] . W$ b' b* i0 g$ @( ^3 q$ X+ F& y #for i in range(10):( I' _7 y9 o1 @' T6 c0 t
# rand_num = random.randint(0, 100) 8 \+ l g* I. m% @, _9 M0 K # data.append(rand_num)+ z% z8 z& D0 m9 c' D/ U
#print data( H, s$ c) H4 l# M9 D! E
t=RBtree() - b" l6 p0 U/ C1 h$ v- `3 T) G6 ~3 t
' u2 i) c4 n* L2 c) o for i in range(10):, u4 \& W* R) y' Z8 H" Q" z
t.rb_insert(data[i]) 3 f0 w) e$ c5 Q/ k( O/ F' U7 } C5 j; P/ ^
; ?% B8 m7 z0 y5 Y1 i# v t.rb_travelse(t.root) $ S5 h: L4 Z- G8 x6 a% D/ s. G# c' V p7 J2 A5 C/ w
print "---------------------------------" " x# n' L) r( n5 N+ W: s0 E3 [7 ? t.rb_erase(data[7]), L1 @# t' l- c9 ~
. O0 X3 J' W, {% g2 L& S
t.rb_travelse(t.root)- d( d; ]+ I1 w# ~7 z7 j
2 A! o4 e$ Z/ y$ m) M3 |