#!/usr/bin/env python / C! |1 k4 M# t/ f% P# -*- coding : utf-8 -*-% i3 v3 e' o7 [6 S& Y z- v, l
2 i5 Y0 D; c2 @ |" \8 g; j$ _. K8 m% S eimport os / \3 P0 O) |% F* v- u0 `import random 0 e0 ]& e7 O" e6 l, A1 [" b& Z# {; a1 ]( Y
RED = 0 8 C6 s/ h H$ |; yBLACK = 15 @& B5 t5 q3 l6 H6 R; ^
, C9 \% Y4 P. o5 c5 c6 v/ O
class Vector(object):$ a, s9 K' f6 H1 a
def __init__(self,x=None,y=None):8 |+ y f; G6 {0 O
self.x=x , S. |5 p5 [) K) {$ L: O; k; E self.y=y " w* v: ~' q* t; y; Z! f/ W" A/ E+ @; h+ t( c# | Z
class Node(object): 7 ~4 Y, z' c: c+ F( O! T3 k """docstring for Node""") @( ^7 T- }6 D5 N
def __init__(self,data=None,color=RED,left=None,right=None,parent=None):1 G: I3 a: u( e% M- O$ ]5 B
self.data = data 2 R1 n# q) i5 n4 i self.color = color6 w0 o4 a: a2 C$ b" `" c" a
self.left = left6 d7 I. t* Y* D7 \2 U
self.right = right7 A9 D8 N4 j7 ~
self.parent = parent ' ?) y! V) V' a- u2 B7 T. f2 D' r+ ^: V, C* f
class RBtree(object):2 V+ ?; w( Q: [# z4 N
def __init__(self):# W; Y9 e; L5 w$ A
self.root=None) M2 k" V6 y' m- B* Y
self.size=0( }3 C7 u/ K" R
' G5 o4 g# V& R' M, i. F! z* z5 F ]
def rb_rotate_left(self,node):9 I" f: ?$ @/ X
right=node.right3 M% u6 s* }/ h+ ?- p8 l
- b7 r; m; @' i0 `& D2 R" V* B8 h
node.right=right.left ) ^7 A' {* i* Y1 H if node.right is not None:- ^! B3 [ u, i, b
right.left.parent=node : y0 n$ m; |; ]) ^3 I 7 z- ~) @ z! t1 ] right.left=node ' v( m1 D }1 |9 [2 J' q% S5 e6 [ right.parent=node.parent ( C/ I/ K6 X7 ~; G7 ~9 W4 G! \0 @- Y2 x$ L
if right.parent is None:( y2 ?: a5 ^; a; R+ y
4 `0 I# |! [) f$ T" q1 T! P
self.root=right2 e$ q+ t& ?8 ~+ }" s
else: 7 R! w1 ]0 c* U if node==node.parent.right: . ]( C6 G# \8 n/ ^. W node.parent.right=right : g; u7 r+ H7 J) R else:( A. F4 t/ g% f# i. G; S
node.parent.left=right' X, }6 ?) N, N7 A: Q: R
node.parent =right4 T( T2 p' F1 u* y7 s
4 [- s3 L/ \; X0 m2 i' e5 M$ h9 S7 H7 t. B, a1 e
def rb_rotate_right(self,node):: i$ M4 b. N+ i* I, Z; Z, r
left=node.left# ]2 W S X5 Q- y* I" k, z# q
node.left=left.right + k+ `3 `0 f& ` $ \) A5 `$ z* W1 r, s, [4 } if node.left is not None:5 d4 @# ~ e% q& G) I" N+ ~
left.right.parent=node ( R, y0 a: @; P3 t " z) Z. X7 D0 O* Z5 T, q left.right=node 1 V k- ]. Q3 N& J9 t! X left.parent=node.parent 6 V, l( g5 ~) P; T# _: ~ - Y2 [( W& J3 o6 k if left.parent is None: O$ n5 k9 p# e1 g2 Q0 K
self.root=left: x$ t4 h7 m1 e( i2 q' ^ L
else:# L+ u2 ^, h; E7 E6 C4 Q7 f
if node==node.parent.right:2 j' p: @, A5 D) C( {/ ^8 N- I
node.parent.right=left' Y9 ]4 Y v3 z9 O+ y4 H5 u# O8 _
else: 2 D$ O/ F( \( S9 ~& z node.parent.left=left j" a" n( Y. Y- w6 ^ node.parent=left- W; L: D8 T' `2 E* i# y- m% u8 G
# }1 ]# h2 a; b# g% w5 ] def rb_insert_rebalance(self,node): 2 p1 f0 c6 u; b! T" Y0 ? parent=node.parent 2 u1 m# N* M5 d% S$ t2 y while parent and parent.color==RED:0 B1 |- ]; |. m1 A5 Z [
gparent = parent.parent 5 F, Q D0 T3 G+ |% ]1 d( e if parent==gparent.left: 9 ]3 t9 K5 [; i uncle=gparent.right . }7 }1 }, t0 u2 ?$ C; k+ i if uncle and uncle.color==RED: 0 j! T0 [. l) L( [ uncle.color=BLACK 2 v/ M# p0 { F" E/ B0 } parent.color=BLACK+ V' A8 V1 a; H/ m% ]
gparent.color=RED 5 a( m# E' F o3 y. V3 U: L node=gparent + v" `" K4 ~$ J' h else: ; v5 w. \2 n" l" @+ r( R if parent.right==node: / P/ r" C. }0 i, M self.rb_rotate_left(parent)( J3 \% }8 Y: g6 V1 `! x9 i1 p
tmp=parent( V5 `. W4 r0 f" p% s1 B
parent=node3 ?5 n, d" Z* P' s1 Z" _3 R2 Z9 j
node=tmp 8 z, l% O7 l) S% @$ } parent.color=BLACK ( F) B, ?; z: Q r4 {- W gparent.color=RED ; P' v- A: g9 y3 R( L/ z ' X# J& F6 w } self.rb_rotate_right(gparent)! j- ^4 i4 L. P8 v6 m+ @
" U1 R) L/ h+ h if uncle: 2 x$ m0 f) G& B" u2 l' h3 m/ U if uncle.right:+ E% I9 X, R# g( N% p! L
node=uncle.right6 F* c5 L f- W: @
else: , D8 b) G) ]0 z2 V# C2 y uncle=gparent.left8 Y# c5 |5 o. r; M
if uncle and uncle.color==RED:2 v+ _9 P+ ~* |' e
uncle.color=BLACK ' _6 J* _, M" v9 ^, d parent.color=BLACK ; l5 }$ D% G" Z3 k+ t gparent.color=RED0 M0 n+ Q0 `, R$ u' Z
node=gparent5 o, u7 R2 ?8 V# @/ U. h) x
else: # @. N& w& ?( ^% J if parent.left==node: " W' |! `; e8 F4 C- s, t self.rb_rotate_right(parent)( s4 S+ d ?4 q6 x% J; `; j$ T6 Q
tmp=parent3 h# {8 x* L6 C0 k- |
parent=node 1 u3 ?: [" z |) L7 L* r. \ node=tmp % c- @9 r5 P6 c) v! q parent.color=BLACK # b: C; M% J% M8 J. l gparent.color=RED- ]' p0 r8 M$ k2 R1 P- V
self.rb_rotate_left(gparent) + h* M+ V- ~. K + i% F4 i& ]/ X1 m if uncle: " n) h9 ?( j+ \; T$ _3 u. ?$ p if uncle.left: / Q9 ~0 x' ^! o node=uncle.left 6 x" m; n) a: J# w+ p; U- Y parent=node.parent1 P4 @5 m# P! Z$ F$ y" b+ C
; i. i1 _4 I( v2 _) S/ z$ i
8 u$ l/ @( W( V. l1 g4 s3 A self.root.color=BLACK8 n' C4 ~# M0 n5 X; x5 G4 b/ w
( }% M1 a7 ~3 ~) [$ o- U
) u* x! n! U( d! h6 d! ~4 \
def rb_search_auxiliary(self,node):5 F7 s1 ^5 A' @
tmp=self.root6 w! G8 V# D8 R; [* q( e I2 Q
parent=None, v6 P! G- g" j+ I5 J7 N% B. [
while tmp is not None: # q8 I1 ]' ~" m) S' T" ^/ T parent=tmp 6 Q2 w) N! k6 T7 s4 L cmp=self.cmp(node,tmp), ?5 d+ m, ~: C7 K- _8 w
if cmp<0:2 s' O. K$ o# U# M& [
tmp=tmp.left ; v ?; m7 F4 w9 I5 a! } else: ( t: _! x: x0 M5 x' a) u if cmp>0: ' x" ]' ~1 B- d6 k2 d4 l6 Y/ q tmp=tmp.right 3 N% K* Z5 U2 }1 M% f else:- S5 {( s. S5 B" g0 v7 C
return tmp,parent ( Y5 E3 ?3 s& i. B) l+ Y6 k) M& V( g
return None,parent $ f; x" q) N* b8 a6 D& o& k& { {& [, w5 u+ N. q
def rb_insert(self,data):! p! s7 ~8 q$ o8 u4 q% A
tmp=None ( A" ]6 T7 ]% J6 c9 |" b8 K node=Node(data)& g: ~- h/ t6 a
tmp,parent=self.rb_search_auxiliary(node)0 N' s3 L" I8 K1 G
% A( c! K6 u: V0 w+ ] if tmp is not None:5 l' m% d. `4 s
return 7 I, o1 A5 R; e D4 l. `7 T: b [6 F+ f; C$ J) b
node.parent =parent9 [+ B& u3 q* ^6 ]5 {$ u+ r) R3 f- }
node.left=node.right=None: A6 W9 D- z7 `
node.color=RED& d/ q+ e+ {% a) V
, ^* R# l5 z) l2 O5 F9 p if parent is not None:( \6 V! Q7 B3 ?0 V
( D0 H8 u7 _* w# E if self.cmp(parent,node)>0: " X- z' `( U- Y1 }2 U parent.left=node: |( \$ o3 F; Z
else:6 w. B5 E! {. Z( y
parent.right=node " `/ p" t6 ]. c& U- l else: . h. [' B2 `& \0 A( R self.root=node2 o0 U( i8 _4 x& `0 s
return self.rb_insert_rebalance(node)2 g, [9 ~/ x' H+ h+ v
X, M. S) ^/ k( D6 h
def rb_erase_rebalance(self,node,parent):2 w" L1 d) z. m: A' v7 r$ A- m
while((node is None or node.color==BLACK)and node !=self.root):) D {& Y) v+ ]( ~) R
if parent.left==node: % }. Q1 n1 ~+ e, i4 b5 z; K. H1 l other=parent.right / X" d# }' [9 k8 w' U8 ` if other.color==RED:3 b; s3 M0 h- y! O$ U
other.color=BALCK % w( L v1 f5 }$ Y7 A# b7 l% j* g parent.color=RED A. S, w# c, P3 H2 ^ self.rb_rotate_left(parent) 8 g7 T" Q# T) \1 U7 _; ^) i; I+ r- ` other=parent.right * B/ l3 s6 ?4 W: N" B L/ u( t; a if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color ==BLACK): $ ~! ~6 i( y) e4 g, M other.color=RED / N* N% c F$ P2 m node=parent ; s9 ^- `" L% v7 o parent=node.parent - R" H B; S) h5 @2 V! h; r* f9 z* \ else:; Y4 q. T$ \2 s0 O0 i
if other.right is None or other.right.color==BLACK:! ]& X3 h$ A7 y
: F/ r/ w6 {8 r5 i; g& Q
if other.left is not None: ' E' {# c ?0 t5 c" [1 h3 V other.left.color=BLACK: `# q' K3 J% U, Z
other.color=RED9 C# c" B2 z; d, c. v/ H: p8 M
self.rb_rotate_right(other), N3 z- J6 Y: ` ]) }
other=parent.right # r& A0 d& }8 X; T; K9 C1 z6 L3 H3 A/ w* P& ~1 r3 }
other.color=parent.color 0 w, D, C5 R1 {8 B parent.color=BLACK7 d( F( P2 C0 V( p1 q
if other.right is not None: " `9 d( z- A, U- u i P other.right.color=BLACK , x) D* L! { w; X0 b' C" h self.rb_rotate_left(parent) 3 ~; X! q# N+ s9 t. p, m node=self.root0 a+ I0 A0 F/ y
break' c! ~: D8 |; D# |: @
else:, `: M- ~2 e% L( o( l
other=parent.left8 g2 ?' `. Q+ E' G2 `& U
if other.color==RED: % P: N5 B2 I- T; O other.color=BLACK- t$ d% @( p3 Z- r
parent.color=RED7 u7 y4 F: a0 z) Y$ R6 V K0 Z
self.rb_rotate_right(parent) 9 G4 L' V. R% N, I' ^4 w- q other=parent.left 9 Y8 ]: I; E; f if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color==BLACK):: |: v5 n- X0 i) s* ?
other.color=RED& T0 V9 H- h) q: b, C: G
node=parent) C0 G: B- y! N3 ?# q1 {
parent=node.parent8 b6 p& U8 _1 K; a, L, {
else: 6 g7 Z# n0 G# P+ \& d4 E3 E$ c5 w9 T if other.left is None or other.left.color==BLACK:" n K) h1 m2 W. M0 O7 J
if other.right is not None:* i: B& C' Q! B, `) w; a6 K9 e j
other.right.color=BLACK 0 F: s1 j' U# c' H' E" p4 d 8 j8 p2 Z4 Z" R9 C other.color=RED , |! u# e" D Y8 n7 q7 ?& ~ self.rb_rotate_left(other) 7 e/ v* H1 a* D7 c other=parent.left , r7 _6 i5 |. h D7 l & w: J4 R6 n. C/ v' g other.color=parent.color , K+ q/ t$ c( p0 }. @6 a) ` parent.color=BLACK- H9 j# V7 f6 Q
. d6 j. l3 `) T0 I+ C. p8 N& I s' I if other.left is not None: % P7 i$ z+ ]% H2 ~: M other.left.color=BLACK4 e, B" ~3 `' H! U
0 c; @3 [0 ?7 w9 c' m
self.rb_rotate_right(parent) , t; b, I3 d# U node=self.root* J- N; l w& q1 I+ z+ T
break 1 L- c) B: I G 2 e/ w/ V! C4 `# x 0 v! h5 k8 I3 i8 |' j7 x$ Z7 ?$ \5 i. k! h+ N w
if node is not None: $ k$ j* h7 I! r$ P& ^7 Q node.color=BLACK ( p; P9 c3 t3 d" j + w7 h2 c ~7 H5 @$ j4 D def rb_erase(self,data):4 n2 l8 u+ ?' k D
tmp_node=Node(data)' k7 c% A# J5 s; X: W
node,parent = self.rb_search_auxiliary(tmp_node) , ]7 h( Z! g. X/ A! w) ^+ T) g if node is None:/ X1 E5 t' J4 U Z- m' f5 I- [9 Z' {
print "data is not exist." ! Q& H! @* f2 K. n6 l3 f& T return & N7 t$ h, N& Y5 Q( J. A * m, E% M/ w# J& Q+ I# G/ G1 W
old =node6 \6 A# B1 y; N( C/ M8 ^
if node.left and node.right:' I7 T. O+ K; o `) m& L) v
node=node.right 4 O! B6 i* s2 A8 w1 \! g& t9 N( h# H5 a( I+ n
left=node.left8 [& C$ {4 f6 z6 }5 }# X
while left is not None: 1 Y3 i( E; m( ]8 ~+ d node =left! O! I1 s0 O. N$ Q* D) W1 W, L% t
left=node.left7 W; t! h! u {% Y- _' i, i0 W/ b
3 N2 e' c$ V5 D2 g/ e, { child=node.right ]2 N5 J/ u! {. w5 t* _* c parent=node.parent6 i2 d" @: d0 w" Z# @8 R
color=node.color ) S4 ^" K5 y3 g6 W* M. C4 A 1 n2 r/ g& w/ a; }" V R; e! E" f if child:$ U* |7 }4 S7 R- ~* }4 c* Y# j
child.parent=parent ; l9 x4 ~4 n" s! [5 g3 F if parent: , m, T! B T1 w. D' y1 { if parent.left==node: ; ]% l; l/ r6 X% h) L parent.left=child2 Z: \. t2 u# Z0 m& e
else: 6 t( T; P7 F u parent.right=child# o- Q# c# @8 J8 Q( Z
5 L6 K9 [9 K5 `- w else: $ n' Q# s' {- d b9 l: o self.root=child 7 o' z& b3 Y; c. H+ q9 C ; B: {! w+ p# W if node.parent==old: ! [* d) S& L3 g parent=node 6 r0 ^! e0 |2 |& Q( Q6 V2 f5 S' G% d node.parent=old.parent. N9 K8 f$ u. e( i5 H1 p) d
node.color=old.color5 L, c% T6 L* N
node.right=old.right$ b6 D& h8 G. a4 l; P7 k2 N
node.left=old.left+ N: ?7 \3 B5 r+ ]" [, I
+ v t) c% V! | if old.parent: & [$ O5 n3 Z0 l+ g" ?$ _ if old.parent.left==old: + K" K. l8 t. O& \) U old.parent.left=node9 g# z P% W+ B8 c- t& ^
else:$ a8 P( _8 r& d, l
old.parent.right=node 1 g4 L2 U" j0 u$ _+ R1 M else: & i3 P# Y, f5 s self.root=node7 P% H% b. i$ |+ I9 h3 ?
! r; S% {1 G* z; `
old.left.parent=node% c1 x' j! G. Q
if old.right:3 D2 b2 N! L0 G
old.right.parent=node; \! v3 |2 O8 f, x$ O8 ~
; y& `0 V( w% r else: # q/ t) m" V! W0 T2 Q6 N1 m( N; Z if node.left is None:( z* e# \1 A) |8 b0 O& F
child =node.right / ]) m( ?6 q: `$ f. k5 ` else:' }# h: H4 |% ]( K- l
if node.left is not None: * ? z& n5 U( x( b, | child=node.left; k J+ A0 P: n/ X$ m$ ]9 @
else:2 ~' e8 z0 q" s. F- t7 j
child=None9 Y+ j6 y! S0 a i5 q+ E* {
parent=node.parent$ u+ ]& L: R, ~$ V; m
color=node.color , J5 q& E; P8 H) X* c if child:! j- N% o" F7 r4 R4 j1 S& l
child.parent=parent1 H) q1 p& e0 Y9 T; g7 o) g4 Z
if parent:/ e3 W' y+ j5 _7 x
if parent.left==node:* t8 F/ `1 ^" H- |" G
parent.left=child5 h" u" {5 P4 S9 _2 x3 ]
else:, V( Q0 I2 L$ v4 ?) [# z
parent.right=child- _6 x6 L _. e1 y, E; s
else:' g: R+ Y: i+ @! a6 g7 C3 q' D2 `
self.root=child Y* u) ^. n% P' i$ x8 }4 r+ D8 p2 D# s% }$ }1 R
if color==BLACK: 4 X6 i% O* H+ s" A# \* c/ G$ h 6 N( Q' c: P( O" @0 ? self.rb_erase_rebalance(child,parent)8 z+ o' v# G$ Z) M1 p
' u; I7 R. `% Q! z- L( h/ X) j+ q2 P* M/ v' K1 m: v: `1 N
def rb_travelse(self,node):: a4 [# e: s# {3 [/ q7 j
if node is not None: 7 D& F1 `5 A; d# c1 d print str(node.data)+'\t'+str(node.color), ]' p$ [" V" C# s
self.rb_travelse(node.left)' @1 V; O$ h7 z' M/ z$ `8 b; A6 F
if node.parent: , M7 s" [& {, j9 ^0 l( ] if node.parent.color==0 and node.color==0: + J* ^6 P( y2 \2 W print "error"7 ~ f; `& n! d' t
return ; N7 F Z0 c0 |) r4 ? self.rb_travelse(node.right) 6 q1 i( w, _# B) w if node.parent: % z& G- Z$ t3 E$ y2 `" ~6 a if node.parent.color==0 and node.color==0: - d% ? A1 r+ h print "error" , q, f( ~0 u ]4 w) [ return( F* e! O6 N; w) r
( T+ n% t* m1 n3 {2 m3 y return. L* W- N* L- T+ @& k
1 X4 ~- C; m. S
5 E7 @$ [6 @# t8 w8 A: g
def cmp(self,node1,node2):+ o/ Q0 U% t( ?7 n
if node1.data>node2.data :" B4 R) I; W% d
return 14 k, {) J) R, v+ k8 @5 e
if node1.data==node2.data :- v4 T( O! @( N! Y
return 0- Z' Q9 t& r. @% L, X9 A2 B
if node1.data<node2.data: $ ^. e5 l2 f( `3 Y: b m return -1& N2 k6 \$ f( f' j; P B$ b" Y; Z
9 p7 M* z' {. t) F/ R" P+ ~$ M
if __name__=="__main__":! ?% V9 P# Y' ~ P4 W, A' Z0 b% z) D
print "main"5 [' K# C3 \ p: d @. c: P2 X* I# `( H
data=[28,6,39,78,6,43,61,56,71,38] : Y. k5 }, d1 d/ D #for i in range(10): ; }5 {$ w/ {8 ~ # rand_num = random.randint(0, 100) 2 h$ {2 T9 f. T6 a. h* p # data.append(rand_num) ( b8 k& p# C/ y #print data/ r# L% ^1 ]3 R& e4 c- v c8 L2 m
t=RBtree() 2 H$ x1 ~- R7 |5 f3 e4 D5 M" i! V7 d: i' h) x) ~, @4 A& |
6 z2 j4 s8 s3 u" ~. j for i in range(10): : s0 A4 r% s' }0 g* s8 M3 ]1 k, Z! F t.rb_insert(data[i]) . |. z1 ^+ E9 R* w! x2 M+ P# B" S2 m$ G! o+ r! y
0 D" D$ e7 S8 i- |4 _3 d, g t.rb_travelse(t.root)9 A* Q3 _% A: x) I
, {" }( c* c. C% m print "---------------------------------" - J5 q! w5 p, r; ?$ B* M% L! f! y. ` t.rb_erase(data[7]) " q9 @, u$ m4 a6 r 7 C* i* _* c' M' v8 O) V
t.rb_travelse(t.root) & J$ D+ [0 M- v I; Z k5 E$ e$ H( {! O$ y: X4 W4 u