#!/usr/bin/env python * z7 d# M. i0 ^. ], D# -*- coding : utf-8 -*- / N) b: a0 y1 R' D; r, r9 E4 i$ u: w7 m4 c5 b, ?" T; A+ x3 @
import os 5 E, |; Y# @% [( }3 w* H, b7 D9 wimport random 0 b# W! [( B+ ~$ I 6 A/ m. V8 M- F8 D! N- F0 URED = 0; j f7 z w0 a" Z& d
BLACK = 1/ r& z3 f/ P+ p; T- E
5 ~, G( @' q. p) r' [
class Vector(object): ) }9 l- }. d; A def __init__(self,x=None,y=None):6 k2 l9 D4 Y: {. o/ b; P4 B6 C
self.x=x& C% H/ [5 d: j! T1 Q% X2 r2 s
self.y=y . \# l: B; o% p: u5 l; a/ ?7 e" O , e* _! s# E2 A/ F! Iclass Node(object):5 ^0 V+ P# R6 o6 y
"""docstring for Node""" , S, u2 e* C) @5 q) m. O def __init__(self,data=None,color=RED,left=None,right=None,parent=None): " F% E2 r. B# E A, U5 m self.data = data 1 u& K2 J# U$ W! B# ?: L4 C7 n self.color = color+ h+ r% V2 ~* A7 P6 j( R, }( f* u
self.left = left . }, |8 l* q# e9 s* n self.right = right % b1 o2 D9 v$ `. g self.parent = parent 8 d& P/ e8 ]- x {8 c0 G- c) L 4 J, [( d! `) o7 Z* qclass RBtree(object):/ Z$ y6 {2 @2 Q! H, O# ]
def __init__(self): ) F% X. I! k0 [8 S, S self.root=None 8 B9 K# d, T7 ~' f r. |* g0 B8 Y self.size=0 0 N3 D$ @6 Q6 W! _2 w; d : w2 m% p4 T" t/ P" M3 j* ` def rb_rotate_left(self,node):) [4 S# ~- E( I' o
right=node.right $ K7 m7 {- |$ ^% ?/ [* g: W. @ 9 ^+ p! Y" T* e( k8 [* V node.right=right.left 6 h/ k4 Y$ v# l; {$ ? if node.right is not None:& {9 F) R6 N. z$ E7 F8 y* F2 h: \
right.left.parent=node - a+ { j$ R9 Q, j4 O, j: M- j; i5 q6 ?- l5 h: O+ L+ F. R
right.left=node ( o5 `6 H: J& M# g( f right.parent=node.parent* R( z9 r3 e; s! M
# l- M* e9 C$ Q* y if right.parent is None:9 v8 V! q$ C4 N1 r( `+ K, e7 @$ r
6 t0 D4 ]- @) C8 ~6 s# ^( Y
self.root=right7 T$ f" _$ ?( j! P) ]% L9 ^* \3 ^& e
else: 6 B4 z& W" i) R, F2 a9 Z0 ~6 g B3 Y if node==node.parent.right:8 r: v7 ?8 n' |" l# m( C4 T0 Q
node.parent.right=right- @6 d: ~, C7 T% J; Q* S
else:" ?- H$ R2 }% i* p4 n. }' G
node.parent.left=right$ ^ W0 |/ V# Q! ~# j6 _! z
node.parent =right 8 \! r' p9 r1 ]2 n/ k9 @ $ ?) b5 s8 h* F k * u' D8 G6 i7 ~. P. b+ d& P" F def rb_rotate_right(self,node): 5 H. k0 A" i! l/ a' @1 k2 C* Y left=node.left % }- I6 W# e& J' ?' ~ node.left=left.right 2 T$ K0 l v, h) P2 d4 o/ P1 e : @' c; v% y+ r# c if node.left is not None:6 W7 v% l& [7 j1 X, m$ W6 `
left.right.parent=node * b$ |; i& V1 ? J8 x, g, u: b" f9 ]+ \' B
left.right=node& D% n' G: O. y5 b
left.parent=node.parent3 D. M8 |" y: Q6 |4 z! \: w$ ^' k) L
$ C- b1 Q+ {, b }6 N O
if left.parent is None:4 _; h X% j$ W, f0 F/ `
self.root=left1 c1 U) h6 k e( `7 s% H2 L. ~
else: , m5 y( w4 |" s. v2 f2 D# G- }/ f if node==node.parent.right: 5 f/ A" m% I6 R$ N node.parent.right=left / G( d$ @, C# s/ ^( q9 G else:3 s& _' ]. Y3 }; n' ^7 k
node.parent.left=left7 p: L1 r" K6 U+ \8 p
node.parent=left8 m0 |. o U& G t7 A" a9 v3 \4 v
& h9 V5 a; W4 \( G# M6 R' Y1 S# ] def rb_insert_rebalance(self,node):" e+ q! [( W! b" C1 x6 h! H, e* N
parent=node.parent' f9 U- }: W* c
while parent and parent.color==RED:$ G$ r; e' z+ K
gparent = parent.parent# k, ?& @+ Y) s( B) j! Z
if parent==gparent.left: / O2 ?. @- \" H: D5 Z uncle=gparent.right% P. _( G% s4 c
if uncle and uncle.color==RED: 5 p. `# ~2 b1 j- l( b& Q2 s uncle.color=BLACK - t! H% G( B' ~$ v; r/ w parent.color=BLACK # {0 [8 Y& W5 {) V) x' z! C/ S gparent.color=RED# o" ?. i C) X# R
node=gparent , o% }8 j6 s9 Y" G2 _ else:7 k, o. u+ z2 c# k% Q% d& @
if parent.right==node: ) a1 n& ~ ~; {& e9 }' G* P self.rb_rotate_left(parent) 0 q8 |3 [( w ~* X( f8 _ tmp=parent$ ~- [ F0 s; \9 M2 C, ]3 `
parent=node g* S& g' U1 E$ v" o
node=tmp $ `+ }; n' |3 w parent.color=BLACK 8 Q7 d. o; y/ F! I gparent.color=RED ! L0 T8 ~! j+ h: g2 S8 c # k2 Y! j3 Y- ?, a4 ^4 M- p self.rb_rotate_right(gparent) l9 c: G4 I: l2 e# d. o1 n o% y1 v
" C& I$ [9 n0 g8 ]) I1 f/ M
if uncle: 9 z3 [" o8 @" T7 R+ m% V if uncle.right:' T" h9 I8 q; b6 Z3 Y
node=uncle.right0 h1 q7 w3 G8 i7 z- t5 D6 k+ H
else:$ n+ I: J' }2 p! _9 T6 n
uncle=gparent.left8 \1 b' \; w3 S2 L- R
if uncle and uncle.color==RED: 3 x$ [7 H7 D+ L uncle.color=BLACK % q. X0 u; x0 V/ M9 ? parent.color=BLACK$ J! J; Z! N0 g* a
gparent.color=RED: q# s1 U4 |" q) t I
node=gparent, _/ _: y7 C7 k
else:9 R2 ?! U6 x) R0 j( A1 W! @) a
if parent.left==node: 7 Q {/ F+ ~* C2 ^2 @. Y self.rb_rotate_right(parent)) H/ v4 q2 j5 n7 Z: K' p
tmp=parent ' n; r6 O1 V: \3 L/ T parent=node; H' |- P" u7 k$ K3 E1 m" i
node=tmp+ `& i6 s- R4 k8 c3 J' h
parent.color=BLACK y' {4 M0 T" o1 o- j: Z3 p
gparent.color=RED 2 s( r. B1 ]$ X: t! w self.rb_rotate_left(gparent) . q! o% G9 |. h" z& \8 Y, Q0 n' S: `8 h/ g5 q- N( b/ R6 b
if uncle: - P# P G' U: Y& A% {( T' v if uncle.left:0 U3 v2 g% @% R* x l6 A2 m
node=uncle.left" B- D# G; a/ p5 J |2 Q& E7 Y& O
parent=node.parent * w9 X1 k6 S) g8 q( C& D: L4 D' n- x% F+ [/ X, I% A# j& P
- L9 {; A0 L2 P self.root.color=BLACK 7 P# h% e# f4 O) b 7 K& e3 J. c% S4 e ) ^4 h- t; |' @% i* ?6 Y def rb_search_auxiliary(self,node):& |, Q; @( K# X1 H
tmp=self.root ; k7 X8 u3 m6 M+ v parent=None1 @- K8 L6 y' p& E' w5 [2 h
while tmp is not None:8 b# |5 w* F) Y" ^+ Y
parent=tmp5 v/ d/ ]3 X: Q3 n* X
cmp=self.cmp(node,tmp): p7 [: k6 T* [' o, r/ R) \
if cmp<0: $ b6 {* T; E* _7 ]( T tmp=tmp.left 2 g! {, u; ?0 v+ `2 Y" e else:( p" n; u8 p5 m7 e2 Q; e
if cmp>0:- P! ^' m, f. G4 X' G1 n# K, o
tmp=tmp.right2 g. D3 v& w' }# f" F: d& P* v
else: 5 S: K. N/ R9 N$ K+ T( z return tmp,parent 9 e5 t& }& @# |% h5 k' O- z }5 j/ K6 \+ h# D* V; Q4 C- U# D) X+ _) ^
return None,parent D( J$ o1 @: H, Q( Q3 W: T5 \, Y2 ]3 Z! b7 ]! h6 `- m( n P" E
def rb_insert(self,data): % l& C: I) T2 \* i tmp=None / @$ Z! e; \. m node=Node(data)/ U& L. J3 Y8 G7 j+ I% t# |
tmp,parent=self.rb_search_auxiliary(node)# L1 V T- L% @9 ^# A- q) ^
\% ]6 |2 J: A& a8 z+ F4 j, c2 l4 h if tmp is not None: ( g- |2 Z( ]* u( Q8 m: O return . K0 }/ S+ Y6 B; V5 `" }3 ~& \0 E6 z. X; u: k( u) X
node.parent =parent / M$ x5 \( c ]$ a5 J node.left=node.right=None/ E, w% @% E. R2 |/ q
node.color=RED8 l& R ?, Z q i# k' n0 p
5 }: `" {: p+ v3 S# T2 v' H3 {% l9 p; Z if parent is not None: 6 `6 W# {' b6 M" G: H" E1 E7 N4 h! D7 w' m
if self.cmp(parent,node)>0:9 y1 J3 Q/ W! l; v& p3 u& a
parent.left=node, J, w! W- l8 n, g
else:6 [/ c9 T+ F& \4 n8 g1 T
parent.right=node . M2 o: {& s. V$ Q else:! u' l* D M3 z8 `, R
self.root=node9 y% @6 i6 e8 d7 s
return self.rb_insert_rebalance(node)9 W2 {1 a- `+ f, e% x
" V/ y: I' n' _- C def rb_erase_rebalance(self,node,parent): . k; i" x$ v; ]* o) @0 c' Q while((node is None or node.color==BLACK)and node !=self.root): 6 I9 W6 f8 b2 |/ I8 j if parent.left==node:- K1 c4 \6 b/ W! C! e5 T
other=parent.right b2 x3 Q/ ^. O( t) b if other.color==RED:# f! ]/ {6 W0 t4 Y( N
other.color=BALCK $ _, `* Q: b* @: A1 n parent.color=RED ! T9 S: F+ I2 \ self.rb_rotate_left(parent)( o/ w3 F T7 Y M
other=parent.right + A! s8 O6 d2 n+ \ d if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color ==BLACK):: _5 H5 h* W# b- ?0 G! ^5 [
other.color=RED4 y; T0 W0 Z! ]- b
node=parent# k( p- n+ ~8 b! Z3 L& ]( N; a/ z
parent=node.parent " v/ t f4 D+ x- O else: + N6 \" |$ G/ }+ L p if other.right is None or other.right.color==BLACK:6 h) |3 s( A- K4 a7 x9 \9 @3 @' S% m
2 ^8 L% w% r. _" X; `: M; o, R5 ` if other.left is not None:: r( b ^* k Y) g+ p
other.left.color=BLACK* n1 N$ c5 Q4 h; J' X' Y
other.color=RED7 c% O- Q' @3 u7 o
self.rb_rotate_right(other) $ c0 \% m+ q: }5 ?3 B+ u other=parent.right 5 Z7 l1 t' B, {* Y1 P& `* z& ^: O1 R9 k% S$ r5 B+ a
other.color=parent.color+ a7 t9 O1 t/ `2 s0 b0 g! Z! s
parent.color=BLACK- _' e" F8 a9 r" y
if other.right is not None: 2 r: W: ]4 N7 T9 @2 u8 Q- n other.right.color=BLACK1 U0 C0 p0 L5 `2 ^: Y# }
self.rb_rotate_left(parent) \0 [! _0 M; T
node=self.root- G) s3 J. _6 o
break . J* [/ L! x' ~7 h$ G) D% x else:4 k6 Y/ g0 z( G/ |, `) _
other=parent.left. E& r$ g% Y. j
if other.color==RED: : Y; k' A5 B& T4 Y% @% n$ h other.color=BLACK1 [" e7 C. `3 g5 e
parent.color=RED 4 `4 N; s2 Q* N' S- { self.rb_rotate_right(parent) 8 d; s; o8 \9 l, P6 f# j* C- X other=parent.left ) |. _$ E4 w4 u. [* [- Q if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color==BLACK):/ V0 e7 d3 l8 \( O# j/ A' |
other.color=RED( @6 d7 z m3 L; Z' ~
node=parent # q( p( E+ z# ^' W1 _, g1 j parent=node.parent* C o# }1 G( b e3 _
else:, g( x* O" i0 Y' T
if other.left is None or other.left.color==BLACK:1 ^& i, a2 U6 D5 a' r" G
if other.right is not None: 6 l3 ~' p2 D; X9 J J- y other.right.color=BLACK . T6 I1 B5 r, Q; | S# _3 B( R- o! L3 F 4 D3 u( q7 [9 |( i4 i other.color=RED 6 e* F! S' A1 t" {1 W8 A+ {$ a self.rb_rotate_left(other)4 N0 L* X1 Z( b' i% B
other=parent.left9 B" A0 [3 Z( D# u. D
4 u @" G$ ]$ A3 O
other.color=parent.color' P `- R" x1 _' p2 A/ X
parent.color=BLACK . T* c# w# [9 r! e @6 K- t6 A" Q5 z
if other.left is not None:3 t7 X% O+ V. R7 @
other.left.color=BLACK6 T8 \7 g. n# q
, [ c2 \' G" Q: X2 u7 k
self.rb_rotate_right(parent) 6 q( [9 H9 F5 F. I& r node=self.root& w2 A( {" k; @/ a- |- I1 y
break ! h5 g X5 {3 m& |* `0 u9 T, u' Z # V5 ^2 \6 N5 V7 \. ] `4 G" ~; s% U/ G' C
6 U" ~' l; v7 K$ U% y3 S
if node is not None:+ h1 Z( [3 \7 j! D
node.color=BLACK : N8 q6 w% d5 k% D' O
$ q: B- N8 @1 ^+ ^3 H( V def rb_erase(self,data): 1 q, Z& I8 S# h# r0 v! I% f tmp_node=Node(data)7 S" P( e# r0 f: {
node,parent = self.rb_search_auxiliary(tmp_node) + p7 Z5 R) {( e0 J/ s7 n) L if node is None:/ k% a4 N8 h- M R" d ~% i
print "data is not exist." : K3 ]. F% E/ g' J" O9 i return A( }; U: R ? 5 A( ^- l! K- v( l9 b8 t7 o old =node* W [4 p: P2 g) V2 k
if node.left and node.right: ) r! F% L8 [" L7 R* F. G node=node.right , p' }0 ~3 a' H: t4 [" V+ L$ i/ Y& _2 c3 z+ ~, P' C _
left=node.left4 v N' w- ]/ V5 @$ G) ~! _
while left is not None: & `5 |+ U' W3 A& d node =left' X7 [. ?& f0 o( p( g- W
left=node.left & L% w$ S: A1 S) G5 Q' T; p! u% a! y# t+ @& u# R+ i
child=node.right 6 t( |% M/ I" }5 \! ? parent=node.parent% H& A# s C' m6 k
color=node.color & T+ `) r9 k" W" s, w$ o , b9 K% F( ]) n4 ` x% A, i if child: 3 \) ?, t j" Z! o8 P/ Y child.parent=parent9 I+ l3 H; u4 m7 P% Y+ U
if parent: * y! U4 H$ B, a3 c M5 l5 L if parent.left==node:7 X" B/ I0 W# @- Z w" s: }5 e) t6 B$ `
parent.left=child% C/ q1 O& w6 r# p [
else: G w) ^" v( d, N" I% y parent.right=child* y: a' c" I( q5 s$ l' f9 M4 Y# o
, w" r& K/ c, m else:3 l6 V/ w* K# @; z
self.root=child' U2 [0 j% j( Y) R
$ K8 Z/ j! {) @! i- g# t' \; |# V
if node.parent==old: 4 m/ D: N, r! J4 Q7 ~0 @/ s parent=node # J1 O( f0 {! z. q node.parent=old.parent " h8 e' l3 ]! x node.color=old.color; j8 C% w9 p) N7 u* F( T( `2 \" g
node.right=old.right, u% p' ?$ C- w) a8 }3 m& ^
node.left=old.left5 O9 `( \. y* f% o3 j0 I
$ l/ n9 D. v5 M, x9 h% j- v7 p if old.parent: ! p+ C9 r$ _+ a% ~* ^ if old.parent.left==old:1 V7 e9 X4 u W1 {9 A" ~4 D1 n
old.parent.left=node& Y1 V, ]/ H4 H7 a0 p# {
else:9 ~) i. E. N/ H! }2 W8 E) s
old.parent.right=node 7 B, g7 y" C# H+ W1 u1 B2 Y else: , ?, T* p6 L0 F _) N9 w self.root=node' ^3 i" {% S! \& i) e
2 L) F4 C) b$ b old.left.parent=node0 L1 j9 I$ V. t0 U
if old.right:7 l* P8 }7 y$ Y: E" E5 V
old.right.parent=node , g# C9 N$ z/ i) A5 a- A' I( p* {7 t3 m$ O4 {" |3 N# E, ~1 M2 \ r _
else: # a; V C% Q/ {2 J W/ H if node.left is None: 2 b( d: J/ e% D' t8 z child =node.right " Y4 T7 \/ T# d else: 8 P- I; i7 [; _$ o- t7 x m8 t if node.left is not None:5 h( J' ]9 C) t: E8 W: w* d5 C& g
child=node.left1 Y% E" N5 b2 ~) g
else: 5 `; q: U2 J& Y1 F. Q. O child=None& U4 o$ P; V# D4 T) S
parent=node.parent! e9 F y, J& ~' [9 R+ B" `
color=node.color . ^2 b5 b/ X4 `2 K' u$ i if child: ( |: Z; g+ P/ _5 Z8 v; q+ E$ A child.parent=parent ! h$ K0 f# k4 B* I6 G if parent:+ c3 f3 Z2 U1 _$ a B# w
if parent.left==node:# W1 c4 G. ?) U( R( \2 ]
parent.left=child0 |1 N/ P* X2 S8 q/ z8 }
else:( x' \) U6 d N
parent.right=child2 g9 @% j! k4 S7 ~1 v% T1 E
else: % q7 M; \+ X9 o! e. h) t self.root=child1 h( h$ d R) f6 c0 V
9 p2 Q" J5 p6 J) y if color==BLACK: $ E, N) a5 r" m( C9 w : k8 k; y6 X) i4 A5 w( y& \ self.rb_erase_rebalance(child,parent) & ~. t1 {( P: Q. I0 V/ A- N* ^2 }1 S% g' I( u4 k! s7 ?
9 _8 Z4 E/ f; U5 Y9 M9 f
def rb_travelse(self,node): & s& }2 @" Y4 | if node is not None: 6 _5 q# {" n. ?0 N* a print str(node.data)+'\t'+str(node.color) : R5 Z6 r" @2 v* d3 z7 x# |, } self.rb_travelse(node.left)- S! [% N& o; b& _ r
if node.parent:9 v- _% I' q# k6 t- v! z# ~
if node.parent.color==0 and node.color==0: ) d; w6 n ?" w% Y print "error" / p, l% P8 X+ g3 w s1 b! U return 9 Y1 w0 [! h2 u2 b2 I6 j) b8 W self.rb_travelse(node.right) $ l2 B) n$ T2 [$ x4 @6 r3 |$ U if node.parent: ( _% L, T' E+ U: G if node.parent.color==0 and node.color==0:. Q4 Q& u$ J+ v5 D6 k5 v1 D
print "error"4 V. V" v T5 T2 ~8 Y e
return2 D" L/ y, C) L/ j/ c& q3 n
' ~ z% S) C; o% b# S return 9 D9 s) t! R4 m5 { - D, @5 N) B$ J + i/ o" M [" `7 G0 A, B
def cmp(self,node1,node2):. z7 \7 T7 M1 ] @# _+ B0 G: @1 v# ~
if node1.data>node2.data : * y8 B% M: W+ Q* B6 a E$ l9 U return 1 + ]. I) i0 r" F9 l+ d# W if node1.data==node2.data : v/ g% |" v$ u: X& d$ o Z8 q G return 0 % ~, c3 H$ R: X$ @/ l if node1.data<node2.data:/ Z* R' y+ ~9 X- v) c
return -1 2 y+ E& E7 k q9 B6 I" U0 `4 Z 6 x# N/ o7 V$ s# [2 I, gif __name__=="__main__": # G8 I7 N7 ~# v4 {0 r print "main". y+ b1 A0 [: g/ p9 S/ z3 b
data=[28,6,39,78,6,43,61,56,71,38] 5 h$ W6 Z1 i ?! N/ _8 T) J #for i in range(10):9 a* M8 |) L( A, Q+ K
# rand_num = random.randint(0, 100) $ m# U x5 A9 V3 y. m. w # data.append(rand_num)* V |! h, T0 D A
#print data & O" _5 x2 F: q3 h7 f U t=RBtree() / |3 E* r) n8 s% x0 e# B, F; `$ w, A- E' b
* T- C8 I9 K/ u5 F ^" g) L
for i in range(10):+ F2 ^' O! U0 \( E& O- v
t.rb_insert(data[i]) H! J: [: k. ?. g" V; p/ U( Y% N+ e# d) L: E6 B
/ }" {, \' j8 {$ Q+ s t.rb_travelse(t.root)' J* |* S7 I" g# e C: W
2 T: {+ @5 U4 b5 v1 ]3 C6 {5 X
print "---------------------------------" # `" E b5 W* C2 z8 I+ t% d2 o: S t.rb_erase(data[7])$ h5 D& c2 I* V( j0 x2 Q4 a
]0 y0 J" Y% M$ E/ R& A/ a7 ^( R, u t.rb_travelse(t.root)8 o% a7 O T5 z9 K9 O
9 o/ q" b& g9 D- d9 {- u5 w8 N