0 [) Z; X- m& n+ {* lRED = 0' s( ^. {8 {; X# V9 a" ]* _/ y
BLACK = 1 1 L, n3 s- e( {. m" \9 [9 y% {# |) ?1 v3 c( C
class Vector(object): - l, b j6 _$ f* z; i5 n: a def __init__(self,x=None,y=None): + ?7 S' T* B- U* E' X1 v self.x=x : g/ K) x% B5 ?( {1 f+ V self.y=y " Q0 Z- G3 i% ~4 A n7 C6 O* [4 `' o: w R$ |6 fclass Node(object):7 V, I0 I* r/ H) Q! q0 ^
"""docstring for Node""": j7 W5 K4 j# G1 F2 G
def __init__(self,data=None,color=RED,left=None,right=None,parent=None):0 V$ g/ c# G+ G0 z
self.data = data ' @1 B- @2 A7 @4 l5 v self.color = color " x$ T7 @$ ~9 y self.left = left n% f& G) t6 n+ r9 M0 { self.right = right9 J. P3 E% ]; W) Z
self.parent = parent$ ~7 D4 M" T& ~+ D& l5 n
3 `& I6 n% Y% u6 l' u L2 f8 p( Tclass RBtree(object):% e+ _4 s8 F- g9 r$ v1 t
def __init__(self):) ^9 a) V6 e" q4 \; i
self.root=None 7 f1 G* L/ n" ?2 \- S self.size=0 ) a7 @& A/ A( {& o# {3 E, u% T / o6 ?0 q: p& l; _' C6 V def rb_rotate_left(self,node): 9 x" f" y! m( c: Z5 [5 m+ Y" _" M right=node.right3 z) k& f6 Z$ K. g( q, v
2 P; W* \4 u- p% J- e% | m' j node.right=right.left( c# f9 [9 Z$ c/ L t8 m2 }
if node.right is not None:9 C" T# e) p3 N% Y$ E
right.left.parent=node' U( P. g, C6 K) |2 L2 ]" ^# h, P; I
2 j1 ?6 q7 q$ A
right.left=node7 _5 y% I- f. j. R( @, P x
right.parent=node.parent $ E! Q# h8 I0 v- a4 M7 a- F; P/ W# ^* ~# I. [: F% W" J+ O
if right.parent is None:8 k+ R7 Y: b4 F; Y$ D% x
% ~: b; v) [( Y9 _' D. \% v self.root=right" T# B6 ^ l; v6 n g, z. u
else: 4 z% I3 ~; M4 U# w: L7 u if node==node.parent.right: ! G2 N7 u" q" p node.parent.right=right+ b5 h. R) F3 U; ?" v i
else: % [; S$ o/ |0 o* D" H6 |+ r node.parent.left=right 6 _ ~8 ], e% X7 N2 Q$ y; e1 m% C node.parent =right; b* \. K& i4 q
; g: C7 F: q# X) l' f8 v( S, {
* ?0 W/ W5 v0 | [' [
def rb_rotate_right(self,node):- L* w8 { d$ f0 }2 b2 Y
left=node.left& i* [0 {9 p8 m! ~
node.left=left.right 5 H6 o9 j8 Z, R # R( X% `: u/ t a if node.left is not None: $ `+ J3 z" [* G8 f- H Z left.right.parent=node$ d+ Z1 ^5 z7 A. j# y
0 K: O- p1 x! t, h: f7 y left.right=node3 P( Z( V' [! A0 U
left.parent=node.parent/ f( w6 t) o; B' q
. i- h. ^, ~2 M) @3 T9 ~ j6 L
if left.parent is None: 8 k) j3 e# u' U y* I+ A7 ] self.root=left3 L# v5 F3 i! p2 F
else:, \0 j- i" i0 ^' O$ ?- y# {5 @
if node==node.parent.right: - [& N7 V' G0 k) p% Z; k4 L0 R node.parent.right=left 2 `: T7 d5 A( H1 r/ F! J else:; E+ F2 B \4 R+ W5 d
node.parent.left=left " C% X+ B( u; i) u/ x7 g node.parent=left 7 b3 P, ?: V9 E0 P 5 m3 J$ s/ c% y$ F7 s. Y. X def rb_insert_rebalance(self,node): q$ X. K2 i. M" m% G: H) i
parent=node.parent- \& m' G: J6 v& c }# h% x/ c
while parent and parent.color==RED:& b& D0 m8 l. ^* m6 b
gparent = parent.parent ! T$ M# K: @0 [* w# g1 K if parent==gparent.left:) o: A% j5 W) y
uncle=gparent.right3 t# ]& B5 C& f5 q* x5 C
if uncle and uncle.color==RED: 4 x5 u7 C3 A/ S" a3 @9 b% j$ j- | uncle.color=BLACK 3 F- q' y. J4 h- d- Q. Q parent.color=BLACK$ {5 z1 g( }: M. O
gparent.color=RED+ ~- W& n$ K$ K
node=gparent & l9 B+ `; c* _6 |: z else: 3 z, c) {3 D4 ^7 d2 Y if parent.right==node:! ]! W" s; O0 d6 [9 n
self.rb_rotate_left(parent); d6 E1 e' J, k9 X- d" d
tmp=parent3 s: C/ S) V, ~2 Y0 d& G
parent=node6 m# G6 ^6 L O% q+ U% ?: V
node=tmp& y( e& D# W- M! B$ k
parent.color=BLACK ) [+ A6 g8 K9 \) }6 \- r* q gparent.color=RED 4 m. p3 m' Q- c$ {8 a ; K" f6 R" V6 ]' N self.rb_rotate_right(gparent)" R& K K4 N: [1 z! F+ i
]8 Q6 u- V: G( W; V, W3 w& A7 e if uncle: ( @) v1 q/ Y% h+ U" b1 A5 i- K& q( |: I if uncle.right: # Z% _) Y3 h1 ]+ u( [ node=uncle.right( C% y% l9 }1 @! L6 j3 F
else:) Q* Y7 n$ l) s3 c4 |. H0 b
uncle=gparent.left \# W4 B# g7 p& C) v- O: F if uncle and uncle.color==RED:' ~# u+ \% Q4 b" ~2 ]) {) X
uncle.color=BLACK D/ X1 f' W j5 z A
parent.color=BLACK 3 V. X5 g8 ^( j, o" }; ^7 W& s gparent.color=RED 4 k, A* c# S0 E O; n node=gparent ; l4 D4 f/ d+ @# X6 h else: 5 Y6 N. R/ H% u+ N1 g if parent.left==node: : e' X8 m3 ^# S" @7 ^3 g @5 u6 c self.rb_rotate_right(parent) ) r% g- t5 k- P2 ? tmp=parent1 F7 ~" I% i2 n* l
parent=node 8 X0 t* ?; G' x5 [ node=tmp , M- L. i2 r) C( J% v5 L- l2 ] parent.color=BLACK; ?3 W; ?! t' G3 s( A' m6 y
gparent.color=RED ( T; y' [1 m0 C; i2 A' _8 I: B' W3 K1 H self.rb_rotate_left(gparent) 7 B) B0 E$ k3 Y- H- x4 e6 ~+ c/ v# ?1 Y5 [
if uncle:' ?: j( s6 P: ?/ _5 }: K
if uncle.left:0 b( i! q$ {& |' W" {# t q; p
node=uncle.left* Z( s4 D0 C% ~* [5 u6 E) x4 [! {
parent=node.parent6 x1 B% o3 x* ^7 ~+ m- I9 ]! A
o) [* S' J; n d; k( Y
* b' |0 S; V2 x8 x* {4 X0 S* H
self.root.color=BLACK: B1 |# B4 J7 B* g) v. ?! g
7 t7 Y" y# ]' a6 W) G8 c4 [ / v4 ?4 n, C) q def rb_search_auxiliary(self,node):# B5 \5 W7 K! y) U0 B( [5 B+ o
tmp=self.root ( ]- i. I, n f; b$ ] parent=None / B9 {1 ~3 R1 D while tmp is not None:8 I) {& q; l) U* i1 {/ O
parent=tmp' m; f7 c7 `! }5 _
cmp=self.cmp(node,tmp) ! W* t' G0 c+ |: Y6 E$ \8 y if cmp<0: ; w# _4 F) c8 N9 o/ Y& ]. h tmp=tmp.left , k8 u4 h0 a% \/ n8 h7 q, | else:* \* u& O5 c5 L9 N
if cmp>0: * t7 h9 W, z5 M+ X% k/ I& H, e) V7 p tmp=tmp.right # O n/ n, H; ?* [, \& L7 b0 p else: 2 b1 l' [* D- W2 A return tmp,parent 2 g! v; c) K) H. h }% i x% ~8 w n3 b- e9 W% V
return None,parent0 `9 C$ v6 U) E. H
' H) ^# ?' \9 B9 `
def rb_insert(self,data): . {! o- J6 z/ Q4 j! c1 Z! K tmp=None* n6 W+ g5 U$ j# M7 s6 Z/ r$ o
node=Node(data) % ]4 W7 O( v# t& j5 q tmp,parent=self.rb_search_auxiliary(node) # B# g! F9 L( v0 p" O9 @ & Z+ i' m- e8 W# b: c' B, G, y if tmp is not None: & R {3 J! _% ~' s! Z6 u return 1 s: p7 X/ N# @6 [* G" a
3 \4 @. z9 D4 i8 A6 Q: J node.parent =parent , j1 q# R: a& D9 i node.left=node.right=None. t4 r5 T8 a. Q8 r: A- M
node.color=RED6 v5 v6 Z1 Z! q4 @) t' o' V! h
7 x. _( H* d, n4 b2 q% ` if parent is not None: Y9 ~9 v! @' L- u7 Z" h2 D: k% K8 D# P( ~ D
if self.cmp(parent,node)>0: 5 O& s6 ?8 u$ C* S; J parent.left=node , G: v L4 f; F6 G8 u" k9 b2 ] else:$ l! |* y- X+ l4 L1 e$ v3 u' e
parent.right=node / t; e# |8 u" j: ?9 K4 b else:+ O `$ E' [7 p2 C
self.root=node ) w* K3 `) H: {8 ?# ^$ D2 f0 x- R return self.rb_insert_rebalance(node) % i K$ j, r/ }9 e2 `. y ( L( `+ R i* L& Y0 g) U5 ] def rb_erase_rebalance(self,node,parent): 4 ^+ ^" E$ u# M9 C' a while((node is None or node.color==BLACK)and node !=self.root): : b M) E0 M, ?7 H0 \ if parent.left==node: z! P a0 h4 w other=parent.right 3 \" T+ x8 i, x1 T if other.color==RED: 8 o/ g- B& Y8 R- [. \5 ~! P4 t other.color=BALCK6 f% o- ~5 _2 L5 Y
parent.color=RED 2 @/ B/ e/ B8 |* y2 ] self.rb_rotate_left(parent)% b# X5 v7 v9 {! @- i( s" a6 X
other=parent.right 9 R& o- N- ?& w' F# i, a if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color ==BLACK): , W6 k" a4 {8 C4 } other.color=RED2 j; c) ~1 w8 S) l
node=parent ) o$ P! M1 J5 Z5 j$ K( f( J; b parent=node.parent9 a) P2 }. [/ [2 W
else: " `5 C" B- C) T0 r+ O9 d: `. k5 y if other.right is None or other.right.color==BLACK: ]2 c- s% `- m% ^ U" M! ~0 c# j7 _% w' R
if other.left is not None: 8 [! F' M8 d/ Q7 w& q other.left.color=BLACK' B# m7 `; [7 `9 q: Q, o" h; j2 |
other.color=RED & P9 b1 a- p; C# `' I( g self.rb_rotate_right(other) ' G) c0 y& x' p* H. w( p, L8 Y2 Y other=parent.right 5 ]& M2 @8 P7 d; a% L3 R5 r3 y% p) p3 K+ \5 ^* ~/ ^4 D: P
other.color=parent.color 8 ~$ |3 F Y$ F" e' g# M parent.color=BLACK0 m/ y4 L- R6 y' e, N
if other.right is not None:. ^. i' Z) h, W9 ]2 h
other.right.color=BLACK : O7 W x. L0 X# D8 a* F6 D: @ self.rb_rotate_left(parent)- {- P" C: t6 h3 ^
node=self.root 2 K" n0 f- B6 x# n; O f break 9 \( c6 R( e8 j/ W) f6 C! d1 d1 @ else: 3 x6 m2 i' {& B3 E other=parent.left& s+ M- k- E; {( W" [" F1 }4 k
if other.color==RED: % \ A' t9 @! g0 `+ Y; m other.color=BLACK, r6 N1 v3 N# \" v( Q& Y
parent.color=RED " T' j/ A0 [/ D- U) ^! w self.rb_rotate_right(parent) B+ l3 `- I8 L( r$ Q0 L3 |" f# ? other=parent.left 6 |) z- }$ Y, ]+ L9 K1 K8 r' Z+ I if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color==BLACK): + k4 A8 d) z$ E/ ] other.color=RED& R5 U: a( ?# p0 [+ F& A$ y, v
node=parent: c b+ e; L8 r( L- Y1 L. m& ^ Z
parent=node.parent ( z- Z+ _( D# \- N @) e: E else:" [1 l7 z5 n- l: U! n/ W
if other.left is None or other.left.color==BLACK: 8 m9 B$ p8 P6 y- @+ P/ o if other.right is not None:6 w$ _% f' x- Z* G) N$ _: T
other.right.color=BLACK9 h8 ^7 e A/ W8 ^
: z; t1 u: |4 b# P& L$ L ` other.color=RED4 b1 L8 U& O3 e$ Z4 Q3 }: |' Y
self.rb_rotate_left(other)$ J. M0 j: e6 u ~
other=parent.left5 Y- Z+ I7 G1 ^" j
9 Z$ _5 D- e- X' q3 t ~
other.color=parent.color8 z9 J* \+ u. l( @' m& g% C: S: P, H
parent.color=BLACK `& e: j3 r- x9 A3 n1 K# ^8 m& g3 }9 [
if other.left is not None: % A; \9 F% w* Y- Y6 ~ other.left.color=BLACK4 ]. Y+ z4 Q" p
( c8 S- f' D/ {2 v: j4 | self.rb_rotate_right(parent) ( n% B" r1 E0 v: {+ v node=self.root . w+ [- `) {9 J6 Z break + u2 W: T! G/ _ k. K$ o . L3 \" `' ~6 R% Y6 C) M! w4 ]* ?9 }8 e% H9 @7 I6 x
6 `( D, a+ g _2 c/ Q
if node is not None:1 ?% u! |, K7 y
node.color=BLACK " j! u+ V, D$ e' r; a: J/ R/ h" r4 j& P8 [; [! Q F$ ^9 I
def rb_erase(self,data):6 ]0 _" |9 H; U7 {8 p7 D: y9 V! Y5 Z% i
tmp_node=Node(data)) [8 d- e% {+ C* S+ e1 D& i9 F
node,parent = self.rb_search_auxiliary(tmp_node) $ x/ F( O# P# o7 ?6 {! w# r if node is None: , X5 d: ~2 Y1 F* m7 P4 Y/ [ print "data is not exist.": h* {4 d0 i ~2 k k9 g" V
return , \! j# c4 C: s4 A9 H" G 9 f. W, I4 \! B& u
old =node 9 V1 j. u7 R, L# e0 H$ H if node.left and node.right:" w5 X# S0 R) G
node=node.right9 {0 J$ v7 W$ o; o2 N
4 w U" T9 @1 o+ ]5 `7 b
left=node.left0 }1 ~4 j! j2 l' U+ V5 G, Z
while left is not None: $ _8 i; `( q& @$ k8 d1 V( a. f node =left0 h$ @% K5 B) l% ~% u
left=node.left; G6 i, S, S( K2 \$ n
3 S9 T6 a3 [9 T+ q% X4 g child=node.right9 `, ^2 i2 x1 ~. n+ T- C2 ^" f5 v" \& a |
parent=node.parent# D3 K& q) H! v0 @
color=node.color 4 @6 }7 Z# `8 s " O0 l" ` A; Z( q if child: + V G0 Q% W7 N9 p1 o+ |3 K child.parent=parent h5 x4 b4 W: H4 N% X* C if parent:( J2 v( c$ K, H% k2 B; Y
if parent.left==node: ; I# n5 U* g0 K! {# Q parent.left=child % b. x5 V; D& t5 g' E else: 4 X6 X+ K3 z+ {5 Q# @$ X. S6 |: Y# h parent.right=child " f+ Q' {+ ]- C- E1 ?: b$ J9 M7 p& |2 I, l, t
else: % k- E$ \8 a: o3 P1 d' `2 N self.root=child 6 m( ?7 N. I& M6 \- c/ J 1 @# [% K$ y0 y if node.parent==old: L: ?0 r1 B6 _2 j+ m parent=node+ F3 e# F$ Z4 x
node.parent=old.parent! e# m& K+ G B# ~- W3 Y/ z
node.color=old.color % h' {5 t, B1 B4 l- k% g3 F node.right=old.right q4 v& Q/ i, F/ f( Z. i6 V node.left=old.left g5 I4 H& |/ X+ U( K* s- u
* X1 M. X# [3 w! A5 D0 z8 X if old.parent: - E8 N V+ P6 q3 [) m5 V+ X if old.parent.left==old:, J+ I6 v! d" X4 p4 g# v
old.parent.left=node- \0 Y1 ^$ K8 W% L
else: M+ o, v/ x2 F! Z& t- C* e) Q! O old.parent.right=node% ]5 ^) R$ F9 r4 j
else: 2 C. _) S" H3 A5 d' I$ b self.root=node , r' T$ T1 N* @1 U3 v3 ~2 @, `2 d% \) [3 h
old.left.parent=node ! z* C, f9 Y; Z if old.right:2 i6 ^# h8 G4 H+ t( b4 Q0 O. C
old.right.parent=node5 E+ }% n, S, }8 i& m' y
* e( x9 z' I* D* c1 T7 \, g* o' C else: " Q' I$ Q/ @4 Q; x# A! }* G+ ^6 i if node.left is None: - ~3 M3 P$ e g) o child =node.right , m B) m5 c- W$ K6 X% |( a else: " Y# ?- {- W3 q7 j1 V! s if node.left is not None:' a; e7 E, J$ n5 g, d
child=node.left: n6 \% O0 J$ x0 K; l- ]
else:+ B; H9 M) n! V9 H
child=None 7 k- G/ U5 o. F( O' P/ E5 ` parent=node.parent. P" o2 _" R( f9 H, G; b6 d
color=node.color( C" Q6 x1 z5 {. L& x$ b. m- ?
if child:* c) E; m: \# B* M
child.parent=parent3 D5 d2 w6 A) ]* N v r, }
if parent:. B o9 P% z2 `# d J1 d
if parent.left==node: # z$ _* {7 S5 T. y" A' ~0 P. V parent.left=child ( d$ |0 O: v& Q4 i else: ) f4 o) y2 C5 X# J/ z* y8 I _$ ]# z parent.right=child+ v3 H+ g K9 s6 r! N+ K
else: ( J; Z% ]- r. M6 Y, k$ V; L self.root=child5 ` B6 U0 S8 i$ Q+ Q8 b
' K$ B( V( ]2 U" _9 h& b8 X/ N if color==BLACK: / c0 j$ B7 X( I2 j' a + M6 T1 j2 y: \6 B/ r1 p- |" T! h self.rb_erase_rebalance(child,parent)6 W3 }* s& U1 M7 p m& ~! N5 L
1 g" Y: }9 v# \* [- j1 M( i `; U8 X# p% t( ]6 z) r
def rb_travelse(self,node): 5 k0 x" y. l, v# z3 U# N! J if node is not None:/ |% S, S4 N$ ^+ H. s. v% y# I
print str(node.data)+'\t'+str(node.color) 1 n0 R! y2 U8 C5 q% ^0 k self.rb_travelse(node.left)6 v+ L; x7 x" y- h5 G8 E3 c% ^0 B
if node.parent: 0 q# t1 J7 f( g% m if node.parent.color==0 and node.color==0:2 f1 S8 l# e" |
print "error" 6 ]2 H9 H3 }/ K. C: N" \ return# W. N( c) ~1 b" i
self.rb_travelse(node.right) ' Z1 K* v+ Q+ V if node.parent:% [" P+ @% ?) h, I
if node.parent.color==0 and node.color==0:0 r0 j; A+ u7 j( a5 G W- q4 l9 H
print "error" , c' O& _5 x" c+ {( q return ; R! e, w# A/ [: s( w$ n3 w5 q; W# ~* n/ Q5 K. j
return o7 x% _ `7 D* h / j0 s; h$ X4 e' s* p$ k' h' }, U; V + f- Z' H& B" f
def cmp(self,node1,node2):7 h5 y" }, ~" c6 J
if node1.data>node2.data : K. L3 n* i, }$ r7 c% Y1 Q
return 1$ z1 q/ Z" K% v# \7 w& `
if node1.data==node2.data :. C" _+ ?0 U; U, b: c6 J8 T; O
return 0 + C6 Q; L" b. r2 E if node1.data<node2.data: , ~) W% {, j' [3 a5 I/ \ return -1 # z$ [- j5 ~, |3 }' S, {; Y; m+ A) E4 d# ^/ [. w
if __name__=="__main__": 4 ^9 i) b+ X' a print "main"# h' D% n0 E. y& C
data=[28,6,39,78,6,43,61,56,71,38] 1 m5 ~% s5 [7 {. g: ` #for i in range(10): ( X- f: L8 e/ H8 q9 u # rand_num = random.randint(0, 100) 0 g+ E! P; w4 ^& n" V # data.append(rand_num) 6 d9 [. p' F* i0 U #print data/ k+ o R4 L6 `( l
t=RBtree() 4 {0 i3 Q/ v6 C0 ^ ! R7 c4 ?" v; R9 w$ B / o$ p+ e& T0 m for i in range(10): 5 H8 ? W/ a; l0 X t.rb_insert(data[i]) ' C) n% f$ I/ X! n2 {- a- w3 _7 m2 @$ P, R* w' {+ p0 e0 _