#!/usr/bin/env python5 A# |* m- Y3 z/ r% c g
# -*- coding : utf-8 -*-; F1 V; r. X* h! K4 s% k1 t
8 m# T3 u4 b5 a# a3 n8 i( d' L
import os$ o5 k+ J2 \4 t
import random Q$ V1 d" J& L' h: z2 u
! u k& r2 D' o
RED = 0 1 E1 e( l( ?; q& a6 ^* t) CBLACK = 1 2 r0 a/ X' `+ S4 n' K% }' W# V" j" v
class Vector(object): 4 ~& }& S) n, D+ y9 L0 n9 U$ C def __init__(self,x=None,y=None): ( W: g$ F9 q) ^ self.x=x : N% N3 |3 y& q6 J5 }/ s self.y=y $ m% L6 h% t7 ^ r# B a3 o; L1 x# F( Z& A: t$ A
class Node(object):+ q# Y+ M! U) i2 y2 S. U
"""docstring for Node""" # p$ W t5 n( X# T$ K def __init__(self,data=None,color=RED,left=None,right=None,parent=None): 1 K5 k8 J2 f. W self.data = data 3 q& d& ?( r0 x8 }- I, S self.color = color+ ^! D" [' f3 T! |
self.left = left, r: h" {1 r- P$ l8 r
self.right = right' e3 u t6 X/ W7 O# E
self.parent = parent 3 M* B |3 x& P7 o% A, z 8 U5 h' d! [/ ?6 hclass RBtree(object):' F/ V/ G- `. w
def __init__(self): # w. x4 m6 `- a* t self.root=None, H) Z& c+ V/ @) Y; s; v& D( P! T
self.size=0/ Z) [5 X1 K+ y4 e" @) E
. I' H3 C, b+ T1 N! n$ N def rb_rotate_left(self,node):! n5 f; P8 n; y" n
right=node.right) ?2 n1 q0 b% N3 L
X% q% T3 \9 P# g! R T, i node.right=right.left! ?$ V( o ^8 D6 S& i" B
if node.right is not None: 8 p" M9 Z9 j7 i5 ]7 {6 O right.left.parent=node , V* p2 g2 F! u4 Q1 }9 B4 R# {3 p$ i. j( U0 p1 R
right.left=node 4 M9 Y6 A1 ]3 F' z right.parent=node.parent 6 X2 Q& D8 r- o$ _. B# g " u. R% z/ e6 o if right.parent is None:9 `9 i, Q9 L. p6 E
& m9 E O2 d0 F% V self.root=right 9 ?: R2 f E5 d8 h4 K else: ; y. P5 q. Y4 F+ n" j if node==node.parent.right:0 q- [* A* C; q* }' N. W; j7 I1 x5 }
node.parent.right=right1 e) q& G% r$ ^8 d" S" t) e0 D
else: 9 @( _4 W7 _" m# t* h: E9 K node.parent.left=right & D4 B' l* r- D6 H$ n! a t node.parent =right 3 F- X. }! g# |) u: ~0 w5 v. k: ]+ w. x% H! a W
$ U; u% H& E* r2 d
def rb_rotate_right(self,node):2 ]; I6 y2 r8 |4 K
left=node.left7 A: Y0 z H/ f5 t; Z5 S
node.left=left.right 2 g' _ I1 b9 T! W6 D, @' a. n& s" f
if node.left is not None:1 P8 h8 V8 q! J" G
left.right.parent=node3 ^% \3 d+ F5 r$ i# g
" X2 \: t( H( T7 c
left.right=node6 E/ }1 h# Z4 p# E) E
left.parent=node.parent 6 I0 j% `$ ~" Z * ?$ Y2 `: j: `. D$ v6 G if left.parent is None:( P9 A. o% v; j" R! e
self.root=left ! Q o; ]8 d0 j# }/ U, m" E else: 5 b% Y+ a0 q! B( U6 h. w if node==node.parent.right: / Y* Q4 q. I; _ _% ]! U node.parent.right=left8 I Z; }9 b' f9 s* i% B, _
else:1 T7 I* k1 a3 R
node.parent.left=left/ w3 D5 Y- L/ N$ a+ {" D
node.parent=left D2 [# N' P4 @
; M) d0 s$ M& n# a def rb_insert_rebalance(self,node): * M& f* _; b8 B7 H8 Z6 d parent=node.parent , C" I, _1 d' y% |7 i while parent and parent.color==RED:8 y% c! @/ V8 X. v, {4 x# ?
gparent = parent.parent ! |. f$ z5 o3 U3 g4 u) m if parent==gparent.left: ( N; Y; i4 |; k/ y) _ uncle=gparent.right l$ @6 F. l7 y. f& T if uncle and uncle.color==RED:+ N# G! u r& ~& r5 O( O
uncle.color=BLACK & j/ s6 e0 A! \& E0 V E parent.color=BLACK . C6 \/ G, Z( Z9 V# Y/ K gparent.color=RED7 d" R6 W9 R# c C" ` F
node=gparent4 R5 {; R5 y$ ]/ N: s" P0 D- V7 I
else: 7 s- z0 o/ l2 x' j if parent.right==node: & x( Q* }! o" Z" V, V1 {4 V self.rb_rotate_left(parent) 4 e5 q8 r4 h! @* \# r tmp=parent$ ?% N2 M+ @- F/ t2 [$ p6 ?& A& T# C& i
parent=node 3 ^1 G1 @/ Z$ S c: B node=tmp / ~( p2 R7 z3 e+ K6 Y parent.color=BLACK - {9 e* F5 g8 R0 v! W0 h8 r9 { gparent.color=RED( m- ?' l+ q# |( {
* |' Q4 g6 T) W9 X P( X& ]* L% d self.rb_rotate_right(gparent) . l$ B8 G; m; f- m2 |3 }* U6 U3 _0 G
if uncle:: O% K1 J0 K9 v; [/ y% _
if uncle.right:* A( m# Q- q7 s0 V8 x4 P
node=uncle.right + v0 s$ A, ]% |9 O& a: [% d else: : \) }) ]) X+ X' }. T% R uncle=gparent.left# v" C; E \) `
if uncle and uncle.color==RED: : x; @5 n2 O$ C) R" N ] uncle.color=BLACK8 I6 c' ?* U- _) G6 D7 n
parent.color=BLACK ! c2 h; V2 Z5 Q' |6 {/ v2 {0 v gparent.color=RED, [* Z O$ ~+ w; ?& `9 E
node=gparent2 c' | j: H* E& G. o9 X
else:% B- H& _( W( j v) R9 n+ W: I
if parent.left==node: / k9 e; j' x; m5 L self.rb_rotate_right(parent)- J7 A( q; r- l1 k" ]
tmp=parent9 R# C: V% a* j
parent=node ( K; F+ c) N2 j+ ?0 N# M node=tmp 5 H7 i6 e9 z- f parent.color=BLACK/ n4 [' F( ]7 w' O5 z
gparent.color=RED & P5 z3 t6 p/ B7 m self.rb_rotate_left(gparent)& j( K6 r |7 G9 O0 Y/ o8 Q
% B; I) i0 V; F' \9 B
if uncle: - t+ v* e; ~* H/ j7 G if uncle.left:, G, Y% h5 v$ V" N( b5 `
node=uncle.left S: Q( |& o i" u% W parent=node.parent 9 a+ o: z4 y7 a- G! q) z* y4 Z 1 j& R/ F5 H5 J& N$ y ! p# ?1 }2 D- { self.root.color=BLACK0 c7 r, v& W# P3 w+ ~% n
5 N1 D$ n4 J) a 9 D2 T0 p* J: a( s9 }( c def rb_search_auxiliary(self,node):3 f2 W, V4 ^' E+ t7 p
tmp=self.root 6 V2 q0 |0 E3 s6 i9 I parent=None & u. C3 A6 V% P/ M7 z$ J8 Z; m- \ while tmp is not None:# L, z- y; G% K( A( ^6 J
parent=tmp % W# @. U4 j& B/ ^9 C cmp=self.cmp(node,tmp)+ P2 B( w% o1 b! a; v; j2 s
if cmp<0:! t6 \+ n2 Q' g0 Z: C9 l/ ^
tmp=tmp.left. T7 }+ g" e% O" T7 n" t' o' D, `" m
else:2 p* u* R' U: g N: q
if cmp>0: - F# @, N" H. w- j tmp=tmp.right3 w. j$ k; k' z- R& [8 W
else:' t7 \. H1 |( f6 n; R+ ]5 p7 a* T$ [6 c" m
return tmp,parent5 @, W# e; O2 d3 Q+ w
# L7 U0 E5 q; B& Y; n# C) G
return None,parent $ S# g. E. V" P3 t4 {* V% L$ c1 M5 d5 G" t( c5 ~
def rb_insert(self,data): 9 R9 a* S* `7 v0 c; @6 X. g2 A tmp=None8 q5 `0 ?6 z7 c
node=Node(data) * G( V; s0 o: z" m* c0 e tmp,parent=self.rb_search_auxiliary(node) M1 P9 o2 h# Z0 R$ t. l5 X; }; b& n3 ]. h7 ^
if tmp is not None: # L8 b( ^ e) z' g) n$ _ return % k, k; j+ G$ }, a) D, ^ z7 j% `- C; T4 L. V% @" o P
node.parent =parent4 M" \' l% N/ W3 a6 L7 J( x s
node.left=node.right=None! o* Y$ s- a- u6 m5 ?
node.color=RED 8 B0 P) {+ F1 y/ C* I/ [* U' l# y9 Z0 R9 f: B: o/ J6 ]; o" s. Q4 ^; k
if parent is not None: F" ?, v# Y; Z$ m* s6 Y3 j ! X, c) Y9 `- S$ N1 _- Q0 ` if self.cmp(parent,node)>0:- A2 h: G: J( ?5 O }! l) I
parent.left=node. X+ v0 r2 {& N" t! P/ L
else: 1 E3 w' T; t3 X8 C7 f parent.right=node 6 t! A7 t$ G& |5 j' A& [ else: Y; `- x* _8 q' R" ~ self.root=node * k- v" P4 G/ C return self.rb_insert_rebalance(node) 4 t/ D0 B: y5 @/ x R - w% l, Z* c' u% E$ `) |7 }6 u; ? def rb_erase_rebalance(self,node,parent):# ?, D1 y. A6 D/ A3 m% e& t+ \5 z
while((node is None or node.color==BLACK)and node !=self.root): ' y! {, S+ {' k6 A$ [# C- X if parent.left==node:. K, L: p% g. y- \4 P! b9 k+ V& U
other=parent.right * ?6 Y- k7 A* c& d+ ]( r! X+ z if other.color==RED: ]# I' {7 V' _# U5 l5 ~' b! J other.color=BALCK 9 u" R v$ {& s( x$ G7 s+ K" p4 L parent.color=RED , |# J" L% l! u- }" F7 ] self.rb_rotate_left(parent)# v, O: x6 I( o* x( b) s
other=parent.right" Q O9 A* y- q& w7 Q/ {& q3 E
if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color ==BLACK):# H3 h4 Y1 @$ Z- y! @- J: V
other.color=RED ; V4 g# r7 e5 n( i3 a4 y node=parent2 n, }( v9 M# i4 i- o. m
parent=node.parent / R8 J: k. W# J* |" A5 [( ~" S, c else:6 d) z+ D/ ] K' U) T) F0 X
if other.right is None or other.right.color==BLACK: i6 J* \! S$ i y6 x' m
$ e0 l$ t1 z9 N- O0 \# l* | if other.left is not None:/ A* o- n8 ?9 f. k0 ?. c& n
other.left.color=BLACK0 C( U9 M5 {& A/ j/ b A
other.color=RED2 Z4 J0 [1 T# I1 Z
self.rb_rotate_right(other)3 e, S/ E/ N0 M, \7 f" f9 L
other=parent.right 0 j% U7 ~# k% h7 \$ h# m! | # T% ~/ ~8 F/ I+ L# K8 ` other.color=parent.color $ ^$ g6 T; A8 T; V9 {; i! N" X7 F parent.color=BLACK . W ?( B. F' u( V# d5 m$ G if other.right is not None:4 \$ f7 @9 f1 l( V& |
other.right.color=BLACK* l# `" h1 W" L1 F) E" ?- n0 N
self.rb_rotate_left(parent)9 R2 i, |' c3 U+ A. u9 Q
node=self.root - C' O3 M5 i: w0 [( o3 k+ l break % d; F* i! m# Z$ r) ~! h else: + y6 u3 ~. e' h* t ^6 M0 L other=parent.left6 j- A5 y* e# y' P- ?
if other.color==RED: ( H& n* c- h* \( L& q- d other.color=BLACK) N' R0 W6 o3 M
parent.color=RED, N& V E- ~ y g
self.rb_rotate_right(parent) / H4 _- S; y# y! \2 P7 P" v6 M other=parent.left : ^# n* x' M- C: g if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color==BLACK): % J$ Z; Z2 m2 O+ I6 L" K other.color=RED ; |& I; b) a; z) O1 j* ` node=parent( |4 _9 U {# d: d/ U. s
parent=node.parent $ x+ e0 J- m: R, k3 i- K' M2 o! D2 x else: ) R" w T/ X6 S. P* x. g if other.left is None or other.left.color==BLACK:) Q+ @ L- l( t! @$ w% {
if other.right is not None: % n. u/ H8 v' a3 g" @ F other.right.color=BLACK! f) ]; u, D) k* `
1 n0 W$ m8 U3 }1 O) k other.color=RED ) q+ d2 F+ x2 H+ k self.rb_rotate_left(other) ; h) W/ b# @1 x0 W a! N other=parent.left " O* i2 c* v% q. ^7 V8 k, b. T' n6 J/ x$ B, K( j+ Q! u
other.color=parent.color% o& T3 m# E- Z0 f) x3 d u
parent.color=BLACK ' }+ Q$ ?3 Q! m/ N/ d: D9 C3 |6 w/ }! g2 ]/ F8 X+ F3 ^* v/ p' _$ ~
if other.left is not None: ! O) ^# V8 `3 }4 P other.left.color=BLACK7 q3 ]/ b' m& E; Z