#!/usr/bin/env python V2 q% C, ~5 r& _# -*- coding : utf-8 -*- 8 z' g6 q" W$ @$ t0 _6 C, b / S2 d$ w0 N& C6 a+ vimport os8 t5 A6 T, L! x' ], [
import random - x$ e9 r. o( }" | / z4 Q* i- m" k K% ?% X' i- |RED = 0 & @, L* s6 L3 b, `BLACK = 1 # W7 K+ s- @" w+ l& E( U8 [; e
class Vector(object): / I' Y" _' Z$ V$ K0 U3 P def __init__(self,x=None,y=None): 0 d: C7 K8 X8 b, ], g self.x=x 2 U5 r1 T+ D9 f! e6 F# { self.y=y5 e( F1 \8 g( L/ j
) z. C2 V* [4 w5 }# n
class Node(object):! s1 n9 c7 q; a K0 b! f1 \% I
"""docstring for Node"""9 X0 B* a+ T7 O1 }3 T5 `$ t$ ^
def __init__(self,data=None,color=RED,left=None,right=None,parent=None): 9 s! R, j3 }8 Q: Q* D/ k% C self.data = data1 e; A, r, ]2 J+ S
self.color = color 7 I/ q. J' _; ^% y4 G. ^9 i self.left = left 0 P+ Q8 `& ~ V9 |: r0 F- w% p' N7 A self.right = right2 \' ]! I! m5 c+ |
self.parent = parent 6 W' G& Q% L+ C4 _/ F5 J, t& j3 o) f
class RBtree(object):/ b; L- y+ v5 ?. T9 _- x+ L1 ^
def __init__(self):7 c2 {% d2 K2 ^) ]
self.root=None1 c& V% i! g0 b9 S: q4 E
self.size=0 1 J0 v' x0 D* N9 Y; k2 z + o6 R7 |6 o+ M; v def rb_rotate_left(self,node): ! S0 V- K4 q3 Z8 u right=node.right 5 o1 w) L; s8 a8 u7 T 7 t& G# @/ E+ B/ C' r7 e" m node.right=right.left3 _- l! L, }' @" E! g" M
if node.right is not None: ( y. X' u( f. }. b right.left.parent=node- T9 N1 c4 U1 }- d6 W) I7 `: C
" E1 `! Y0 m! K8 _; M7 @ right.left=node 4 Z# P' {1 X% K: L. M4 C$ m5 h right.parent=node.parent " E4 W9 r, s) X8 M4 O ! j0 Y; O9 Q' X3 Y$ o5 I if right.parent is None: , h* r) ^( r- F1 k0 x! f8 m $ G, o6 U! Z/ l' f
self.root=right - b! V8 _4 B) [/ E else: , z2 F9 l/ R1 B) v, Z8 @ if node==node.parent.right:$ t( L) A3 c' O2 x+ f
node.parent.right=right 8 V; Z+ e/ b' ^* M: ^3 ?5 m7 I else:9 U! D5 D0 W5 Q- G: g/ `7 f
node.parent.left=right 9 i: k% W" _4 \5 |5 d node.parent =right # h- \( {+ |& c/ Q5 X' q5 r6 l9 `- e- j3 |7 ^
& B% p$ ^+ E2 H7 U def rb_rotate_right(self,node): + e c7 V, R/ x3 {/ ?. n left=node.left 9 }! k4 t& |0 }( @7 T, F node.left=left.right( C/ k- K# L4 f. a- x5 v
4 K( t6 m# C5 k. O6 a D. s9 }
if node.left is not None:% [1 c% m6 d( ~( y
left.right.parent=node6 ]% u/ s8 q; q9 d. |0 g, M; Q
7 \, \1 y4 w3 A6 ~ left.right=node . D3 v6 d6 C1 [# e' { left.parent=node.parent : i4 a ]* t3 @# {/ w" z" _$ I) f2 V
if left.parent is None:; G3 j2 Z0 J: |- I3 v0 k
self.root=left , }! H4 A. \# _" P* N0 ` else:3 Y; |) M F, @7 |6 E' I
if node==node.parent.right:; c# @/ G+ c4 U' H' z$ |" E9 c4 e
node.parent.right=left! e# j3 n. x& |
else:0 K7 r- j/ P5 ~
node.parent.left=left. o. c/ k% a( w0 L) a
node.parent=left6 P& r8 H! Y6 x) m
: E2 F; F% g0 w- c8 O' G def rb_insert_rebalance(self,node):' l+ b! L% i7 k, ~2 s7 D
parent=node.parent% X% z6 `0 q) s( F( }: o( Y
while parent and parent.color==RED:& {% g1 `: r; V2 P; d5 D
gparent = parent.parent ( [; \5 P' N5 A+ `# p! x$ ` if parent==gparent.left: 9 N' s( f! T1 r uncle=gparent.right 9 c; Q) _" ]" `6 \ if uncle and uncle.color==RED: 4 [0 \5 u% j# M- y' r uncle.color=BLACK/ U$ }0 K6 G$ K) T# R4 B
parent.color=BLACK ; D% l1 [: ~, ^5 y* n gparent.color=RED0 T8 z) R, g1 w; x
node=gparent# K9 Z- `' I/ s, c6 s) y! V8 A
else:) J" B( S ^+ Z4 H3 q3 p
if parent.right==node:5 F b6 X1 D* B! N0 X/ ^
self.rb_rotate_left(parent) ( o7 a z. t0 u' T tmp=parent9 U- e7 ?+ D0 U% z
parent=node " C, d C: |# w2 \9 W2 q$ a" m node=tmp7 h! X2 _/ W E' ~# D: @
parent.color=BLACK # o5 s5 I5 e+ Q gparent.color=RED 1 [1 ~5 g! a/ C5 N) }( h . q4 [, q! Q7 L ]' I+ l self.rb_rotate_right(gparent)* p+ D3 ? B) {- P% ?' }4 m
1 @, [6 U7 A+ N* M, o
if uncle: # ]" D; x; K2 }0 `9 d if uncle.right: ; n7 w _) k$ v node=uncle.right , a% o5 ^. k" H; H else:# R% Q$ `$ W3 z: S. Z
uncle=gparent.left) m' i6 W: ^7 _, G/ _1 V" J' w2 ?
if uncle and uncle.color==RED:. P% F) ?3 `0 ^$ Z, ]3 @* q/ w. W
uncle.color=BLACK * {2 N( p/ s1 A0 q parent.color=BLACK/ y7 _' g5 j) l# k
gparent.color=RED. ~% y) g0 r2 y# y/ h) F4 Q
node=gparent; d7 v4 i5 a1 m- ~. C
else:/ G: o0 V, U: j4 n- O6 S7 q1 M
if parent.left==node: 4 \' L/ M% \7 w# I5 v- W self.rb_rotate_right(parent) 9 `# U: O+ C0 R) E7 ]: l7 W tmp=parent" V- |% l5 E, O0 _7 M% r
parent=node5 p0 R7 E5 @4 g" _4 N# ^
node=tmp 4 S! W, _) j$ ~3 f+ J6 k parent.color=BLACK - g1 p5 y3 a& r3 U) B2 \. X gparent.color=RED . V" u& R" d8 _' j( c9 V self.rb_rotate_left(gparent)* a% `% U; ]2 t2 w6 W2 G2 N( w
) {9 q% m, a5 V- G; i% b+ |
if uncle: 4 F% y. `" ? f$ e6 r" C if uncle.left: 8 D+ \3 n0 E' @0 z& W) b# Y2 p3 P8 e9 a node=uncle.left 5 T- `, R3 X( _: L/ X8 t/ V parent=node.parent 8 j L: \1 {' P# H# b2 {) D$ Y; D$ k3 ]+ v) Y
9 h4 }( d3 {( _/ v( o self.root.color=BLACK2 I. z+ q' y: y4 }& o, Z
. |$ z- F* u [$ B: p0 V) ~ 0 K' T2 s$ i( r" \. \, V9 F# [
def rb_search_auxiliary(self,node):( Y; e: ~6 g3 l5 c
tmp=self.root ) v7 G5 u( l' p$ `3 E* W' v parent=None 2 y. L; E! Y2 n2 K" i$ `$ M. F0 J while tmp is not None: 8 Q) c. W6 r6 d5 w, [8 D parent=tmp8 s. T$ Y6 L* b* O7 K
cmp=self.cmp(node,tmp)9 g6 C* g2 ]$ X. B
if cmp<0: % X" |9 a# Y7 T tmp=tmp.left 9 @" d7 k+ r, w else: ( j" a( S9 U& A- G' C& Q if cmp>0:+ n) g+ \4 `, @' b5 }1 k* P" Y
tmp=tmp.right) N- q* s# K# H) i
else: 8 K* q, m% H5 N G return tmp,parent9 X9 n; w9 S1 s
( V/ f# ]+ P J0 p! E def rb_insert(self,data):/ V8 o1 K8 k" a% ?& O: {
tmp=None& c7 f- [! P. L# W: N% K
node=Node(data)# d4 A. T3 G2 \6 d
tmp,parent=self.rb_search_auxiliary(node)) ^2 t" c. Y. I: i0 I) `1 ?& @
* S( A# C/ o; w' I3 h if tmp is not None: 3 E1 o; \7 G0 c* p* [) D/ I return " P/ P0 y& q- ^0 Y
; n7 |7 g2 l% ^0 I: S4 x! A! L5 O& A node.parent =parent g- L: ]* F( M; ?/ w4 x2 u3 O. n
node.left=node.right=None7 Y R V f4 ^. C8 o9 y
node.color=RED7 v4 r/ ]4 V1 N# Q( K
+ K' J2 Q; ~3 B$ k$ A+ D7 j
if parent is not None: 0 Q/ G' j( v! i; m ) J; V; ~% ], O7 u6 x if self.cmp(parent,node)>0:( G1 {5 r" ?0 Z
parent.left=node 6 i/ y6 k9 }3 t! Y else: - \7 {0 R3 Y) X% K7 `$ ~, W& u6 I parent.right=node & J1 n2 H' R! c3 d( c else: u4 o7 O# C9 E+ l
self.root=node! J* k; Y H/ B& f
return self.rb_insert_rebalance(node) @7 U6 o" c2 `, e' q K8 B
) N1 Y; ~6 L. L# } def rb_erase_rebalance(self,node,parent): $ E1 _1 f! F Z6 c while((node is None or node.color==BLACK)and node !=self.root):1 S; i ]0 I$ z1 V; v- y
if parent.left==node: $ t8 I3 L/ e3 S' B3 s3 p other=parent.right 2 P& [, c/ k g1 M1 u if other.color==RED:& q0 H3 p' E( q x4 h7 C
other.color=BALCK ! M. w9 i! j/ P parent.color=RED! m+ B' I: G; K" h4 b* P
self.rb_rotate_left(parent) z& A8 r1 h; |# A; u other=parent.right; X% l# a8 U3 J' ~! n
if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color ==BLACK): & @5 ~$ o8 C$ P h other.color=RED ) R& o6 H4 j1 j0 T node=parent $ Y& q" _9 x( Y* H5 T; N/ R parent=node.parent: a4 l. t7 ~* V( D5 B+ u4 ^
else:3 j; `+ ]+ u( C& c
if other.right is None or other.right.color==BLACK:# O; j+ E" Z# B/ ~; G
* ?' l0 E, S4 ~0 x" F+ F
if other.left is not None: 1 e) M3 H; B" G ?7 f other.left.color=BLACK7 h5 q. }9 _: @8 d0 G; |
other.color=RED. t' x* F% Z/ M3 l) @
self.rb_rotate_right(other) 6 `( y" X: |4 W) B other=parent.right5 u- a+ J6 W% x! e b5 l9 V
' @/ [# P) j* Q* T' G: m! k2 U other.color=parent.color. \+ K# v- x$ K' ]" O Z7 o
parent.color=BLACK2 q1 V7 t* z5 o# ]
if other.right is not None: 4 v* ^) o' U4 @+ ], C ] other.right.color=BLACK. _7 n: D- u. t$ ]' e/ [$ i. r7 D
self.rb_rotate_left(parent), o9 k( v2 D* t5 z" Q" `! ]
node=self.root5 T1 B" c% T1 P
break ( `/ ^' m" T4 L else: * k; o5 \* Q6 A3 {; ~0 T3 { other=parent.left5 F/ m7 m( U2 w7 q# `
if other.color==RED: + J- e) x. R* L9 p3 E other.color=BLACK/ E7 @ T( N! C$ ]3 s: [% Y7 d) t. ?
parent.color=RED5 n( m" L; O# S8 ~, X. v
self.rb_rotate_right(parent)$ C' [% O$ Q- P
other=parent.left3 M" g: G5 _- ?( _4 y! ^, w
if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color==BLACK): 5 t; L! r& G# A- q8 g* |3 \6 j other.color=RED . n# a+ }. Q3 M( S# f node=parent + v9 W2 J. b2 ~' j6 \; l parent=node.parent: X. @: I [# t& o- Q7 l
else: + n$ s6 T" {" X& ~2 X7 q# i if other.left is None or other.left.color==BLACK:4 {& x" B6 T# ]5 K# }
if other.right is not None:3 H- F" x7 E0 u- M m$ ]8 \
other.right.color=BLACK% J' Y3 E3 D. c9 G5 Z) t! p0 \
8 L+ ~% R: |- z9 L$ \
other.color=RED7 r: L9 n8 M7 ~+ x9 K7 ^
self.rb_rotate_left(other)* |9 T) u; y) v" s& J, O5 t8 x
other=parent.left$ P- o. e: J0 F2 E' ` u- E" k