#!/usr/bin/env python * o$ p8 {- b3 C5 C# F& q7 {* h3 ~# -*- coding : utf-8 -*-" l$ \4 V D! L$ k! R1 T1 G7 u( d
5 P- f3 t) Q0 h; d! }
import os : o1 k$ z9 o" ?: y7 Cimport random+ t/ B: D& u9 c
3 x2 J& A" M: y' o
RED = 0! X n- T. W& n+ @4 Z- |5 e
BLACK = 1 * y- k! Z( q! o" C& G5 c & C& v! L K d5 ?9 \5 A! J6 _class Vector(object): 5 @% K) s1 Q, V: z def __init__(self,x=None,y=None):3 _" D. G' G5 K% b% x# Z
self.x=x - i$ m/ x$ f; `& R& \ self.y=y# F/ C. O* N7 N5 Z. _7 J6 G4 S+ L( G
/ x3 q. S0 s1 M& W1 t" Hclass Node(object): ; ]4 a* ~' Y _) [8 u """docstring for Node""" / C9 W( `$ F! a# l* M) ^4 i3 k- g def __init__(self,data=None,color=RED,left=None,right=None,parent=None): n( _- U8 g9 W" E: f% x3 H self.data = data N t" T' ^4 ?! Y self.color = color , _! b& x- m6 l, f A self.left = left1 O- ~! `$ E0 s) y
self.right = right5 `2 J( y/ L. |7 v
self.parent = parent0 Q7 x0 B }3 _: H* Z
/ Y0 o0 [& y' Z9 Y: e' t
class RBtree(object):" F$ g( V3 r. y# o l* l
def __init__(self): ( G5 D( k0 y* H7 W- s( r' @* z; H self.root=None ; q: M6 }' _$ B, f7 p2 u9 ?% K self.size=0 0 T; O$ u& [# C( w8 s, t $ N: E( S, c! d) j8 ^" m4 l6 w def rb_rotate_left(self,node): # c/ E: Z) @4 d) r' ?3 J right=node.right 8 V, ?- B- a# o+ C; N; b) Q$ p5 D' }1 I7 x4 [& p
node.right=right.left' G! P# l* F j% Y! \0 H
if node.right is not None: : R/ p( W- V4 w$ ^ right.left.parent=node7 _; X9 d" o2 G0 e, r! P o
8 V. m! N0 `' a4 q
right.left=node+ `& @, S$ R8 N: V, J5 a
right.parent=node.parent 0 @4 `: ^- m" C: j- e 1 j0 d: \/ r3 j; c if right.parent is None: 1 {* H4 x6 ?8 a. u " _7 n$ T& H; {- H) F
self.root=right( l: x N; n [
else: * k& U4 c6 S7 @' n N3 E. { if node==node.parent.right:8 I% S Z' y" g( X3 L
node.parent.right=right( i- G% V/ C# \, o: P
else: " c3 c9 L8 Y5 A, a3 ? node.parent.left=right( Q; x6 ?+ X8 f" X0 Z
node.parent =right0 `* c* c+ Y2 b) V: Q2 r/ p- p0 d
m, Z* r! f. z, \: l
1 L8 }6 t- D2 B# ?6 U9 a
def rb_rotate_right(self,node):+ ]+ h6 i7 L5 D J+ Q |
left=node.left ) {" @- T/ V- R$ J node.left=left.right5 l/ Z1 z$ U8 Z: b6 j0 @
/ C; w, l+ _7 {0 e2 ~( ] if node.left is not None: 7 n2 E" p9 D; K. Z left.right.parent=node 0 E# j2 B( P$ Y+ _ ; m( K" V$ k: w- F7 r. x( \, E left.right=node3 c Z- f1 g A, d4 m
left.parent=node.parent : X' }% a' w+ _+ |, M4 J; _% ~% l1 ~$ X$ i1 i% D- P
if left.parent is None:. Y: K' d1 J- B" \$ r( V; }
self.root=left 8 I6 J8 }4 r! Z7 Z: a, n5 { else:, d: O$ s5 s& @' N8 Z
if node==node.parent.right: I7 n2 j2 |5 Y% { node.parent.right=left - ?5 C1 J5 _1 V& X8 a, E7 {! ] else: 3 ]) u9 R: K) m+ w, [. g4 K* s/ |& V node.parent.left=left$ G4 b! A, G$ J- G/ x, X
node.parent=left ( f# r! g5 k) `* U2 S( E+ V3 i6 {: ^# j6 J- ], c: Y
def rb_insert_rebalance(self,node): 1 ^( ]+ x: z' _4 V, r7 x s+ o3 c# Y parent=node.parent' r2 w% x/ O- z/ k
while parent and parent.color==RED: 9 Q% r+ M ^, V- p" a! b7 W gparent = parent.parent 0 U* H: j, n* {2 Y2 v if parent==gparent.left: 0 D N% w) q4 E8 o1 Z uncle=gparent.right! M3 a2 i/ }" y6 c
if uncle and uncle.color==RED: 1 w. h1 W( R% k6 U uncle.color=BLACK) ]8 U9 D2 s H) G0 T
parent.color=BLACK( h m/ g w( V; A& Y: `6 ~
gparent.color=RED ; O5 c6 t9 X8 R9 K, f node=gparent $ I: g. E; q! S( B else:8 ?" ]4 S5 D: d
if parent.right==node:) F! y: m6 L4 d5 g0 S% [$ }
self.rb_rotate_left(parent)3 V' F0 U- `; ?4 f! A7 T
tmp=parent7 g2 D+ v9 \" h4 [/ V, {
parent=node 5 k7 m) N4 z4 q, Y node=tmp ! E9 c5 W1 y M% D parent.color=BLACK/ b, j, }. i6 ?0 T/ V8 j
gparent.color=RED" e) ?1 Q( O1 x$ S
+ v) m j( W5 ~& t3 E; J+ q self.rb_rotate_right(gparent)& }2 W" c' T! V& c1 a5 r
8 ]; g3 @: F1 o' q5 {* v( f( Z2 t7 o if uncle: w" }& @/ |* U& t
if uncle.right:6 i" _5 X) t& t# K: g
node=uncle.right* K0 M! s9 T0 {) P
else:/ ^" H. O+ B: m z6 t. f3 A
uncle=gparent.left$ j) k0 ^: t3 y9 m5 P) X
if uncle and uncle.color==RED: ) H6 z" b( r5 ^ uncle.color=BLACK1 z- z0 F* @2 g9 V4 x, X
parent.color=BLACK 7 ^8 e: Y9 R% X, I$ N gparent.color=RED 5 g. \) o+ y! r M4 v3 W" Q node=gparent `2 s8 r2 a h! b) h
else:5 X3 I# f# e/ E8 N. ]7 C& w
if parent.left==node: + m: Q+ q1 v0 s& |5 U self.rb_rotate_right(parent) % F+ B: K% \6 r7 ]/ c- { tmp=parent' v% w0 W( `7 {' g/ P
parent=node1 X* G2 [/ c' y7 X
node=tmp) _+ m) k! X2 N' R: {7 a
parent.color=BLACK " P/ ^0 K6 h. {9 N# c gparent.color=RED 8 [. G2 {; i- F, U! z+ b self.rb_rotate_left(gparent)$ h1 d. V" H- X0 ?! X; s
/ V! G8 b5 J. r" s if uncle:1 n4 I3 O/ e$ ~$ K* I4 o
if uncle.left: - j9 t" I% ^4 c0 J% }" g9 k, N node=uncle.left 6 h: f v, y, i; } parent=node.parent , y7 Z% G2 Y i8 m. B0 n2 a$ } % h% }. E g* i4 _+ V! k1 c5 U* ^8 q# m' u& k
self.root.color=BLACK/ P5 ^; m$ g% G
$ S6 j4 ]" l8 p$ ]: @8 x
* N4 c, Y& E0 X6 s5 w" L
def rb_search_auxiliary(self,node):5 W; M: y" [6 L l6 e) i
tmp=self.root5 ~; W, W# d* w5 e A
parent=None : L2 l/ K$ B' C1 ~6 J& r while tmp is not None: * @# X) e6 ~6 Q0 g: h( j, \- z parent=tmp 2 ?2 h$ _3 o3 l& H2 T( a5 e! C2 i cmp=self.cmp(node,tmp) 6 z4 W6 h4 ^ f2 i# u3 @ if cmp<0: # f( [6 T9 U6 \6 \+ y% r: | tmp=tmp.left+ a) a7 ?7 p* X7 O8 k0 q& f% N; W
else:5 T: m( L+ v2 M1 f# ]) _2 T* \
if cmp>0:0 N! g' @" e M" N$ p: ]' n
tmp=tmp.right) ?3 A2 |- [2 D& B4 j! y
else:6 r3 p/ }% \7 }8 ?% C; W
return tmp,parent/ @ `# I: a8 _1 G6 `6 D1 y' O# E
, E$ J. b% _ f* `: S w( v return None,parent 6 \: K) v; R; o7 t. z7 L v+ N/ n* b1 \
def rb_insert(self,data):3 p& O' S. ~: f0 h
tmp=None 4 @( |) m! |, J; A1 S node=Node(data) ) t; J3 r7 A( y6 ]5 W& R) n tmp,parent=self.rb_search_auxiliary(node)2 R& {. r1 Y3 C+ |3 g
4 H9 C* z% @1 C# g
if tmp is not None: : E/ F9 f" m" M0 @ return $ c' a; D* k9 c/ m- s; _8 F) v + d. c' m$ @# d' `! G7 W" v node.parent =parent ) e9 t& o+ E" j6 X node.left=node.right=None 5 |3 F4 U* K [8 S6 w! U node.color=RED5 S9 ]0 t& x) X3 j
/ o! V; y5 P: |9 s8 y: q if parent is not None:6 U& O; _* D4 y4 {5 _; u
e' s8 g* @, I& i if self.cmp(parent,node)>0:/ `) V3 y5 B, Y3 l
parent.left=node* l: d+ b q# r* r+ F. n
else:) V% z* C1 T: u2 G; ~3 C
parent.right=node9 r) I4 m. p Z) H
else: 1 Q. J: ?* {1 }+ A self.root=node . p3 L* ~, B* {" z' n" W1 x return self.rb_insert_rebalance(node). I0 B) l; K/ B8 S, H* g) c" S
q1 b/ l- I' Y( R, u0 c6 p$ y9 k def rb_erase_rebalance(self,node,parent):1 y" O, @$ y, k8 P `
while((node is None or node.color==BLACK)and node !=self.root):( C9 Y$ a5 p) D" `
if parent.left==node:, R$ E5 w2 K6 i
other=parent.right8 R# V) c( F% V" e) W) q: R* Q/ g
if other.color==RED: 5 h/ m" ]2 L8 \6 S5 m' Z other.color=BALCK % E0 V& V$ k( T6 L7 P# v parent.color=RED, E8 @: G8 T( l, @$ j2 i: H6 B
self.rb_rotate_left(parent)7 M" ~" O, X7 p2 b8 p! T
other=parent.right: J" p, I/ k6 j
if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color ==BLACK):% L3 p: E+ ^: X
other.color=RED$ |! `( \& R2 q5 i+ C) r
node=parent $ B( }1 e6 d/ j% O parent=node.parent5 B# {4 i& C: i6 a: g- l
else: ' z m$ B( G* b0 I. T; s) u1 ~$ | if other.right is None or other.right.color==BLACK: 1 |0 R# G$ x; |0 Y( h1 L: [ 5 ]- \* g2 M( f6 @3 P if other.left is not None: & R+ b5 j4 d. k! \/ C9 B other.left.color=BLACK " I9 }( l) P4 o; z' {( s7 X7 v K other.color=RED / U- j* y, U) Z7 S6 k. y self.rb_rotate_right(other) " a7 o6 u$ V- R3 }0 a5 X5 J other=parent.right / ~& a, C+ C* g& D! K2 Y$ \1 N% Z6 S8 |; t3 z, t' B
other.color=parent.color' r5 B# h% J( P/ Y4 Q" B
parent.color=BLACK ; W4 Y. r0 f3 W! b9 ~$ e if other.right is not None:; f9 J1 R, f; [$ D+ T
other.right.color=BLACK % ^! S+ s" Z' }& k6 J0 o self.rb_rotate_left(parent)- X: Q! C, m1 K
node=self.root2 A" b8 m) F& U/ B0 a/ g- f' w" z
break 6 o- ^ T1 f! V% b7 T else: ) d6 Y& d6 C' o) g: r other=parent.left $ M1 R8 o6 f5 [5 d3 G1 o% e if other.color==RED:- j: v' _/ A2 |7 |! I9 u* e
other.color=BLACK2 i1 M5 M: ? m3 ~0 i+ i
parent.color=RED( q: L3 ]1 A5 W0 W% S; [; Q
self.rb_rotate_right(parent) , c3 C+ P- q- t other=parent.left( f: E0 q1 P- l) D- M1 b3 j' `% {
if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color==BLACK): 9 o2 A# U" @- P9 V other.color=RED' E/ { S+ _3 F- Z; F7 F
node=parent ' r; J8 g$ n! F( m) ]" Y# L- Y parent=node.parent # Y6 Z( V i: T else:8 y" F( V8 M2 o
if other.left is None or other.left.color==BLACK:/ f5 p) E3 B: M. c H/ u. ~
if other.right is not None:5 b" Z! |2 w- i6 o* ]8 j
other.right.color=BLACK 7 [% Q0 w! B& R9 a& N4 {6 T( k: a9 s8 s, `" b) P6 b% }! W4 i: V
other.color=RED. E& a8 S3 r% K
self.rb_rotate_left(other) 8 Q0 m7 t: Z8 f1 i- k; }" v. ^ other=parent.left1 v; k( |& D5 a2 e3 l; `0 h1 B
1 a9 p, y5 [1 g: n0 X5 J
other.color=parent.color * m3 O9 Y- p1 z: V1 I( J parent.color=BLACK 3 O- \% a5 d) i8 B/ Z0 n" X; o+ Q, f' O7 u. y
if other.left is not None: + o5 w7 {6 ]+ b1 [5 { other.left.color=BLACK / k0 [+ [* H7 L& F1 I- ~& d! P & R9 n$ I' p/ Z5 V' F7 } self.rb_rotate_right(parent) , c7 j3 P2 [1 Y$ ?& C$ q node=self.root 5 |" k2 Z( W) |0 R) h/ I break * H4 @; a) Y3 [+ p4 s q ! \7 P- J. V$ Z0 c5 I) {, O) F0 Q, |3 D" S/ J1 d0 R
& r& F- L. h" a3 {9 X# F
if node is not None: % Z% J0 |* }7 G6 \0 M0 l node.color=BLACK 9 ?4 f8 U2 j M 1 p- y* [( Y' m3 i$ } def rb_erase(self,data):% y) Y8 d9 Z$ E: G
tmp_node=Node(data) - R4 b% j8 D! h | node,parent = self.rb_search_auxiliary(tmp_node)7 v& g, J7 a; F) J/ f. L9 h( m
if node is None: 4 q9 f% o1 T' O9 z3 E3 k, v print "data is not exist."0 {" `8 i) \" P8 v* z
return / ]. \9 W) F; u: C# Y% p 1 Q l) r! q! z6 I8 y: l& _& Q old =node* z8 R3 G: ~% U& C( D
if node.left and node.right: - |( p, a0 l! x node=node.right- b4 \# q, w) z6 n
; m7 ]4 N9 j) u8 S
left=node.left' z `, S: a9 l# K I
while left is not None: ! J4 M1 V/ A- x& Q3 f6 V node =left3 z8 a5 n. h3 s) e3 P3 S+ i
left=node.left . F2 M4 ^$ G! W; K) R; ]7 _0 v2 h, R# D+ V0 Z/ R! j- r/ I
child=node.right s2 T6 ]! ~, T4 n/ i9 F2 p3 I
parent=node.parent8 A9 w. o6 |/ m @! k2 L( R( V
color=node.color ! R, K I. o) O" `, B " b1 \. }. r+ C c+ X if child:) i$ z" V I Z2 Z
child.parent=parent1 v7 s9 c9 C1 o, v
if parent:( n7 J8 L" h2 s- a/ K
if parent.left==node:, C$ r4 ^" Z2 u, T& Q' A( C
parent.left=child 9 ~$ `$ H! I/ ?/ f else:3 \( p2 z2 y$ o6 T$ B ]
parent.right=child ) i6 F! k% U$ d8 h z( K; j. F/ m2 m d6 G* W
else:) D3 H( @& ?* L$ T% R8 N
self.root=child, L& S2 f8 ~; g: x2 }
) E [0 E2 k* K! {$ E& o4 a3 D if node.parent==old:2 @% ?; a% ^# j5 a; N
parent=node' g1 A: \, `- G& i* |8 q1 }7 S
node.parent=old.parent / e. ~- z @* C8 Y# u+ K3 Y9 K node.color=old.color6 f1 a" Z4 Y( V9 T0 R) Q( m
node.right=old.right - l" y7 Z' h* o0 j2 g" P node.left=old.left* @2 _% b! a( Z; c
3 C, Q$ {" Q; l$ S3 F( t if old.parent: [! l. H2 \+ Q if old.parent.left==old: 2 ~: `5 s& z: S+ |* g$ R9 U old.parent.left=node 3 I7 J# t6 h( y6 l else:* M7 l9 i, J# V6 Y, C& d! A
old.parent.right=node ! `. ^- D9 _7 @ o else:" A' z; d2 ~) b! L! ?
self.root=node / x6 `( i; W5 x4 R7 a & M- S# m/ y2 @( K' o. g2 n9 G3 K! X old.left.parent=node 6 H/ Y: f- W; J5 B& P& n* w% S if old.right: 8 L) B% U- n8 ^/ \# Y7 B old.right.parent=node K* i4 @4 V9 i' C8 w! D) ?
5 n0 B4 X6 v& F- i/ j# p. o% D0 v' T% Q else:0 _% e" l+ o8 B" K* V$ @: B
if node.left is None:# ?! a. {) C8 s7 f9 B0 N
child =node.right7 F& D( ]4 O- t: ?( k1 @
else:7 z4 s, Q9 _. y. C( F* m7 K/ q5 e6 j
if node.left is not None: a6 l* q) V- T2 s9 E. }8 g0 k
child=node.left: D5 \' D+ ?3 z9 g3 j5 U) ]8 v
else: : }9 H# C w/ P& m# Z- s7 T child=None. l; ?% N& H4 l+ S% o
parent=node.parent & v3 Z6 \$ W* V" d color=node.color 5 y' h+ C0 G8 C" h! K0 O2 Z6 C4 k/ r if child:4 {1 @8 l0 [6 t1 e$ j9 A; {5 d
child.parent=parent! V# M0 |) |: j% ?
if parent: Z7 ]8 H* f, ^- u
if parent.left==node: 2 _) Z/ [; b# W4 M parent.left=child# u+ i3 b8 B% h& _
else:( T a9 t% Z# y& t1 f
parent.right=child& t9 k& b4 ]9 v' K& S( A
else:. B# ~) J# T. W) p' E
self.root=child % ?! o0 t- u* i; N# Z" B 6 s! l: J8 Q ~: q5 V. N if color==BLACK: * A; v+ F$ } \4 v J/ O8 \$ X& v: \4 i; ^) I! k
self.rb_erase_rebalance(child,parent) 1 D( n( H/ o2 ]( d, _% q+ G# P , F& ]( i8 F8 N ^1 k- r) u ! j1 P7 E, a% _4 ?! ~5 D0 V+ @8 R def rb_travelse(self,node): : v9 m" b/ l7 {# ^ J" f if node is not None:, l, L1 \& z8 _4 l; P- `8 {
print str(node.data)+'\t'+str(node.color) / Y9 A# l/ o) ~# L self.rb_travelse(node.left) : p% s, k: U: }2 @. ~ if node.parent: ; F6 R+ x, a6 v8 a8 C: _. U: j$ F% E7 \ if node.parent.color==0 and node.color==0:, O6 c2 H# y3 t/ N
print "error" 5 L+ E% S" s! K. I return1 g& }4 H9 A# `2 } Z6 \# I+ s
self.rb_travelse(node.right) . I8 p- b [5 F- d# |% F: I if node.parent: 2 g; v9 s0 R( H; z, r% O4 \ if node.parent.color==0 and node.color==0: 4 d& E- N& x* e; {" H print "error": R6 T' X* J$ p! T. _
return5 B8 x/ u+ B& T, [# A0 b' N
+ z0 f* ?7 M3 S. y! w* l0 x
return/ ~/ G& R, z/ q1 q. D6 d' M
& r: s) e5 k+ Z. | $ p. v7 U% `. y, j& M
def cmp(self,node1,node2):/ l# L7 J5 C- C( I9 T4 x, H
if node1.data>node2.data :0 | _5 [0 L/ L; y9 N* A2 q
return 1) B/ n& E" `! F3 n7 ?! z
if node1.data==node2.data :3 [3 f: ?$ B* q9 s5 L
return 0( d4 `. \2 ~+ d4 b+ R4 U% i4 Q, q
if node1.data<node2.data:+ Q# Z1 }6 J: k+ N0 H
return -1 6 F5 y" G; v* T0 x5 Q9 G/ T/ B9 P( {' v/ g+ S
if __name__=="__main__": ! @$ O- _* F3 z) A' W( Q* o print "main" , U, @# O( h5 |: U) l" _ data=[28,6,39,78,6,43,61,56,71,38]7 X. g+ p& A$ U! a
#for i in range(10): 8 M' ~6 R) A8 J2 B& ] # rand_num = random.randint(0, 100)/ W n& b. t8 u4 Q7 e$ _
# data.append(rand_num) : m" Q+ [( T1 s6 m# ]# V5 a. t #print data # {0 z. O/ v# p9 ^( u2 X t=RBtree() / Q, Q7 }) ^7 S: z3 M( ]/ k( P & |; T& ~0 a! F " K; D! a6 w* \/ {- l9 X for i in range(10): ( D4 ]: m8 X4 F( o# V% @& I; J% } t.rb_insert(data[i])* f' U7 I5 \# y4 x1 M
- O) e! `1 T2 _6 t& s# D; Q0 A2 G
4 C$ R" L/ M+ \
t.rb_travelse(t.root)8 c: k6 `3 x+ ?1 j- T
, r& B$ d/ T7 S$ w print "---------------------------------" : W9 s' E8 @0 e& S t.rb_erase(data[7]) 8 N E1 U- T6 [/ f5 `" W0 y6 Y, n% j # _) h: q# u, G
t.rb_travelse(t.root)0 `& E2 _! p! a" Z) O( i$ `7 q