#!/usr/bin/env python 1 F5 q0 R4 b" s% K) [+ h2 x3 V# -*- coding : utf-8 -*-& l1 t$ d# m& g( e8 j
( S% K9 Z+ U n& _# y( [4 N7 N
import os ! V: u! ]" _7 s1 j8 Z3 i9 timport random . ]( X5 p$ G; G& M9 q( @ 9 O( R2 N' u; B$ a2 w# t9 pRED = 0 / }" I- @4 x9 tBLACK = 1 b" Z7 L$ G; _; E( @0 ^ Q' m+ L ^7 Nclass Vector(object):* }2 x5 U5 H4 f! K7 q
def __init__(self,x=None,y=None): 4 d% y+ X+ W' y8 A/ X self.x=x. E" E$ R7 D6 ]) c4 c8 ]
self.y=y' ?' p' m4 o5 H
+ W* ~1 d8 P& g5 O) E
class Node(object):# l) I _) @* h* S/ \$ C
"""docstring for Node"""/ U# n6 Z5 h: \+ {& G* u
def __init__(self,data=None,color=RED,left=None,right=None,parent=None): $ t& V$ e# v1 |& i self.data = data: q g) v& Y( Q! I# N4 R
self.color = color ; f `; R8 `: g self.left = left) }. L9 q$ T9 c+ b4 A/ R
self.right = right+ q5 _) h6 R9 I! j
self.parent = parent ; }7 |+ j: s4 v$ r) M T( K& W5 F- @5 m3 N# X7 cclass RBtree(object): ; x4 x; j3 E6 B% p0 X def __init__(self): 2 ^4 m c7 ^) x& B. V" a2 A% I9 Y self.root=None " I, j/ s6 ~5 ]" _ self.size=01 `4 Q, @! \$ W3 H! S1 g
, F4 t; O: `- t3 Y6 V) [6 L def rb_rotate_left(self,node): ' n4 w& e9 u- U. J' G. {. N, H right=node.right' U' S- a' `' T `& G3 g" `
5 \1 ^ ] p2 y% @1 J( e) j4 A node.right=right.left 5 _, q% N- B$ S# A# f if node.right is not None:5 }6 p/ y. _6 H+ e) _% n
right.left.parent=node ( f9 ]& t8 I y% p$ K- ~+ Z - f9 d. i- y: S4 z/ c right.left=node 0 f* y: \: b* h" \ right.parent=node.parent ) J4 H( D5 _2 y) `9 v) a. S# p3 @' E4 [5 s4 B1 @
if right.parent is None:4 l/ H1 w" i g1 S' `
4 o& y+ R( k) m! K D' Q r% a/ d
self.root=right2 y: K4 c$ h) G |
else: . C+ h; [7 U$ I6 t if node==node.parent.right:/ B; E6 y. U. k1 r( Z( a
node.parent.right=right # J2 E3 l& O, T7 e9 F3 m+ Z else:: P0 x/ B" W% g
node.parent.left=right + E2 j8 P& M7 F" R" W$ U node.parent =right) X2 X: U( x" ? l5 T$ i
. A+ b$ }2 i6 V( Q
1 F5 Z: }/ Y9 o6 r0 V# [
def rb_rotate_right(self,node): + \- f0 \& `4 Z: k9 N left=node.left * ^! z$ d( |9 A' V node.left=left.right8 k9 I% e! |& o/ V9 p* ~
c9 p$ U6 [( J+ b6 T, x if node.left is not None:, j, {% `8 F2 U$ J, d# l: ?6 I8 ^
left.right.parent=node' e+ O/ X* i. G0 X4 h6 t# L
1 b* J& R- s3 w4 U5 e6 w
left.right=node2 m+ U. K y0 L0 j3 y
left.parent=node.parent$ w1 c+ [/ w5 K' L1 h( v+ T, R" T S5 e
& g- S0 L0 G: A: M o2 N
if left.parent is None:; W3 ?- S2 \; R1 q9 A! {, {" Y% h Q
self.root=left # N2 D) W# A( }" L8 E9 M$ t else:9 \' A% w( _! F
if node==node.parent.right: # `/ K6 N. n( L9 _3 S- d node.parent.right=left 0 v% z+ O, i- r. u$ L else: 5 O5 d% y/ j! h" K; s& G8 W, B node.parent.left=left8 c2 {& C1 Q# `7 O" d
node.parent=left- {2 p d0 [+ e& ~
c( n3 M u6 c0 [. a+ l4 |# d0 { def rb_insert_rebalance(self,node):( k. X3 G$ [* D/ }/ b! B) w
parent=node.parent9 B1 U$ n. D# t: B& _' l: R1 z
while parent and parent.color==RED: + x" g# `( D, @9 k+ ~" u0 g gparent = parent.parent ) }* q* i( b# V. P W if parent==gparent.left: 6 W0 X6 I5 r+ @( x8 J uncle=gparent.right : ]# M/ _6 n0 B b- Q7 S# E/ e if uncle and uncle.color==RED:# p. q" z& {$ F
uncle.color=BLACK# b8 ~8 W3 F" ?
parent.color=BLACK c( p% }" A% Y, B, Y
gparent.color=RED |) o6 b9 t1 W% d$ x, k
node=gparent 2 {; t" F2 X. {/ ^4 L+ v7 { else: / N @8 ]4 q( q' R5 m! _, J if parent.right==node:+ s J5 e2 N: q& H; s
self.rb_rotate_left(parent) 5 V5 @( k2 |+ N1 t6 E/ _2 K. E tmp=parent 0 l+ o7 B) Z" `& H, \ parent=node - ]2 V5 D' F r3 V3 X node=tmp $ g* v- [8 q4 b' F7 P! P, N, J d parent.color=BLACK& w. \% m- J* K/ H& R- q0 G
gparent.color=RED & C1 m& o7 ~ j* J9 U9 T3 I) U/ ~' ?5 t8 G$ f) O1 @1 n$ t
self.rb_rotate_right(gparent)4 k6 s( q5 o. K4 r
; F* t9 z$ ?3 g4 D if uncle:, K5 Z8 }+ z5 N4 S ]
if uncle.right: ( T) w. G- e; T- s6 @: ^- ^' x node=uncle.right 7 h0 ? m& C/ q/ t% d' [% J else: * T. @( @5 Y. G1 O8 C# d4 v5 D uncle=gparent.left " q: Z9 _' m; w' f& w8 T if uncle and uncle.color==RED:: a @7 G4 j6 B9 n! w
uncle.color=BLACK # A) B5 g/ Q7 C4 h# i. _* b parent.color=BLACK- I/ b/ }$ v$ f7 T
gparent.color=RED8 ^' W3 h1 x! o
node=gparent( D* q" P% C5 w7 d
else:* u- L# T9 P9 ~1 b: K0 j( |! F0 L
if parent.left==node:) s' D* L# C$ G
self.rb_rotate_right(parent) 1 _: D' i7 w# E9 I# x tmp=parent1 V' \1 G2 B _6 u6 m
parent=node7 {* O& T9 b. E% G/ P9 D2 ^6 Y
node=tmp & `2 D$ h9 l- C# ?! W parent.color=BLACK % |- f5 A5 f/ e2 c9 o, X1 @, G3 F gparent.color=RED8 q& B3 f, e+ M2 c% g
self.rb_rotate_left(gparent) + u! x) \: X! [! n0 S1 M; P8 m( m" r7 O% P& C2 v1 q' t0 q
if uncle: . x" U% _7 _1 B& E( o/ {" z t if uncle.left: ; g, {: \0 I7 r# N( U! h node=uncle.left5 j' K% d! _- O, H- a5 b" w
parent=node.parent $ P8 ?: x7 K2 N9 X: w! q" g/ M1 \' i- z7 P3 l& t5 f3 Z
: {7 D/ [1 a( b: a6 n0 ~ self.root.color=BLACK% v( O) ]2 T! O! e* V
* C$ Z$ `9 H+ K6 F/ X1 g
6 p, T$ |: s# l1 K5 j7 ~
def rb_search_auxiliary(self,node): 1 X. o) Z: _; E0 y8 [+ _$ e tmp=self.root % ^( C2 E- S$ o7 v6 h" [ parent=None+ A: ~- {2 M, @" v
while tmp is not None:2 R$ w; ~9 V4 N# Y
parent=tmp i) V4 R! C4 L( M cmp=self.cmp(node,tmp) ) I/ o' Y- |; I if cmp<0:8 v; d# X" b$ t. m4 m! u' D& c* h
tmp=tmp.left ( _" S4 s9 N) @+ C. _% e9 H else:6 j4 T' \$ H* _+ w6 p4 Y
if cmp>0:6 W& q, W6 s% Z9 u& Z
tmp=tmp.right ( F1 ]$ Q; Q' U0 ^6 x2 W/ ? else:. M8 n4 d! B3 @6 H1 t
return tmp,parent $ q+ R) S; u- P# z G/ ?- I * }5 a, ~! K- Y E3 i- \9 A return None,parent) X, B' l9 o" d
$ S3 e; s- y. |9 m2 {) E
def rb_insert(self,data):, ]- I/ ?( ?/ b x$ k$ i/ {5 a+ d. H
tmp=None A3 i" F) W* [
node=Node(data). P" D, A+ J' L. O7 |4 m2 P1 C
tmp,parent=self.rb_search_auxiliary(node) ' @- z1 f/ H/ l: h # O+ f3 P1 k' e5 H7 a if tmp is not None: & l$ N$ l1 X" b' ?/ N# \% j2 [ return 6 l* \ R' T/ v" @8 _
' r0 P! y' q( t! W
node.parent =parent" p& n0 Y$ }5 ?4 c" H* K. v
node.left=node.right=None : D4 _% z( v" f! v node.color=RED; u0 }# J0 u; M6 b a) Y' z
7 u& M6 ^/ M" D& r& K& \2 d, a
if parent is not None:: H g( j1 e3 I9 R
; F# p% }/ Y/ u* M4 d$ ~( {& _* p2 E$ I if self.cmp(parent,node)>0: & K* M9 p3 H. R9 m parent.left=node0 C" d" Z4 z$ b! R. r7 e
else:, `' a9 l' N0 U" K- }: K9 E
parent.right=node 5 T& b) }' m# [' L: n/ e) P/ h( ] else:6 _; r/ y3 ~" g/ c
self.root=node! c3 @3 |& F7 W6 _% u8 I2 g
return self.rb_insert_rebalance(node)$ B9 [" X6 Y4 |% e7 m' @. l2 t
4 r, ]* s0 Q5 M n3 i+ o( Q def rb_erase_rebalance(self,node,parent): - V) R N% a6 e7 T. V% i2 E while((node is None or node.color==BLACK)and node !=self.root): ( i* W: K, [0 c% I if parent.left==node: ! j5 v& m; b( w' g0 s0 w other=parent.right 9 v& b' _& G0 H" Q if other.color==RED:. n# c$ g. c# l' \
other.color=BALCK 0 p: H f' h& W* j. L& Q parent.color=RED 1 n$ {4 e0 C8 X; W) T self.rb_rotate_left(parent)" o7 o# H* r v9 _) {6 U
other=parent.right4 l, W* J) d$ o2 w3 Z5 ~6 [# c
if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color ==BLACK): . R7 ? j# p, _ other.color=RED 7 V/ p" `/ N1 e3 ` node=parent* F. J. y! f- o" G% b9 G
parent=node.parent & Q2 O# J: A7 b: R1 Q else:6 H5 v3 L/ j1 f9 m2 X
if other.right is None or other.right.color==BLACK:& W2 q/ B `4 r
! \2 b3 q. r; W& j/ n if other.left is not None: 9 Q/ E* b8 h( X: \9 S other.left.color=BLACK% [4 j# u5 W$ s1 x
other.color=RED; T" i# Q7 F1 z4 H, x6 `
self.rb_rotate_right(other)8 w) q) R( S* Q- b1 V# f A1 r
other=parent.right - b: Q4 M$ L$ \8 i4 C `. W/ G1 o) q1 ^- O* v1 @8 \2 `" ^
other.color=parent.color " G* U( s3 b1 R9 d parent.color=BLACK9 j# \8 B/ Z8 ]0 c$ H
if other.right is not None: 2 o3 P4 U) K, m. e other.right.color=BLACK ; }8 b: p) }, p4 z& `" j self.rb_rotate_left(parent)% t, [- A+ C/ d- c1 A% f, r0 _
node=self.root. w& L# e( V8 j+ s' j+ S* _
break F! s2 W- r" q6 l! \0 F6 s
else:5 }) H) w/ X9 q! y+ A3 q* E
other=parent.left * V. N0 ~9 R. r6 ~. Y! e2 H6 W if other.color==RED: 4 S2 P6 z4 k2 K& L other.color=BLACK * m# A, E! j1 z j B5 \) \2 r; u0 B parent.color=RED9 y6 _7 \/ w ^% b6 X
self.rb_rotate_right(parent) . K( P4 q* p0 m2 I% _$ L% T other=parent.left ) _- E0 e# h i. M2 @ if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color==BLACK): + U3 f, a8 y2 F# S2 I" j other.color=RED$ s5 X) _$ ~2 A/ e$ a
node=parent+ B+ }1 p$ x! D* r9 y/ c% u/ S
parent=node.parent 4 z5 D" O1 ?3 q/ k else: 0 w4 c& T1 }& ~: n2 [ if other.left is None or other.left.color==BLACK:3 Z4 I7 c2 d# [( Z* c) j
if other.right is not None: - m+ ^6 d% Q7 B/ O/ s5 G other.right.color=BLACK1 l# y! }0 \) N* X6 j9 X* y
2 w- J0 t. T) u* r s/ p- g/ B: P% S
other.color=RED / O6 u9 W9 h/ R/ t4 C/ F) R self.rb_rotate_left(other) ! z8 X4 L' N: `* Q other=parent.left7 G4 K& c y' ^1 g& P8 A
6 s9 ~& F- \( A | other.color=parent.color; g+ O) P0 J5 @& z' \5 L6 j
parent.color=BLACK" p- s3 U+ F0 | L! t% b( Q
2 C; P; @- B% f* [
if other.left is not None: " y7 h- o- W# d S other.left.color=BLACK 4 J7 i' d2 I1 B# Y2 J 0 E3 f- U0 C% W. H self.rb_rotate_right(parent); V5 }! H6 { q: F8 u
node=self.root0 k: z0 s) r) x* J/ P
break9 l, ?# E! r! }* P+ L
: ?6 P& |( U4 Y" {/ g/ A. ^0 o D2 k% y- l, }0 W- D. L
4 E& Q+ |- a3 _( [; y+ B8 }" p5 r, G if node is not None:+ t# J3 t9 {) v; ?( n. g
node.color=BLACK 7 f* l/ P- W1 N; z* d" v
# s. n9 H5 S6 w% a8 [) s def rb_erase(self,data):! e. ]- y7 E( H2 F8 S3 Q- @1 J
tmp_node=Node(data) ' F7 _/ {0 R7 f; x% R# B) F node,parent = self.rb_search_auxiliary(tmp_node) # U6 U1 ]4 j+ D: N# ] if node is None: . I$ S0 B; `$ [1 ~9 d2 i# C8 D print "data is not exist." [3 o2 Z8 v. E0 {: K3 h return8 d; j0 q* F: M; S/ x
w3 j& P* k) O% D
old =node % ~0 F: j# W& P* ~5 n- L6 { if node.left and node.right:8 l1 y$ U5 I; J* u4 H+ q5 |
node=node.right$ ^5 \1 N0 A$ w4 ^1 l
; I8 y% A, P3 g5 C3 M. T
left=node.left 3 g \7 ]4 ~8 Q0 l! |9 F while left is not None:* V/ z G9 C* c! y2 a
node =left# Z2 c$ m s) {$ {1 L# K' f
left=node.left . T7 _! {0 a. q6 L: c! X2 [/ h9 k8 n+ B& r7 W d9 H- Z
child=node.right ( o0 D2 E9 p' C: m parent=node.parent; q. h v+ `6 X3 u
color=node.color / A! d _0 K/ h) C4 D5 w# w. k + l2 k/ u, x/ P8 F. [/ ?7 A if child: ! ^1 b7 G1 ~, Y+ f2 e) C0 V- q2 P- b0 l child.parent=parent ( G: e0 i! e. h; V if parent:* s6 B7 W3 o/ e+ V
if parent.left==node: 1 R0 s9 q6 r0 s- s) ?% t parent.left=child " d) M8 P8 X# d/ @7 z; b- A else: 6 J7 q9 ^% F) r+ c parent.right=child . o0 `1 l& N% D) L+ o P0 q 5 w& B8 l' f# N# ?# j else: ! X/ O; @9 H) x/ v- i self.root=child 5 y6 I( [* F( F; H6 t- n* v, z( E4 y# a. T9 Y
if node.parent==old: * k, [2 g/ z3 R parent=node; r: H4 x1 t! O. R! j9 \
node.parent=old.parent+ Q- ]' ^3 i( F" I# Q5 e: P* O
node.color=old.color; Y3 @5 V8 v9 ~3 c2 A% w8 c
node.right=old.right 5 s e9 l# P! p node.left=old.left `' ?2 {; l7 t) j
" g, b. j3 |5 ] if old.parent:1 h; B( K, }. m3 w
if old.parent.left==old:+ o1 R1 h: y k1 P( r7 S5 ~& M8 I# x3 B
old.parent.left=node 4 t# D% O5 Y" E* X/ r, O else: " x2 S/ Z# D7 s {" n# V old.parent.right=node+ M H' N9 j: N' d2 M2 w
else:. {- K7 q3 [' s# j9 ~
self.root=node & }9 u% I4 x1 A4 u. S- y ) k3 _' U+ C2 s( ?& `7 r old.left.parent=node, U8 I' v; G* i: L
if old.right:: s- U$ `- p0 V6 T, g: q
old.right.parent=node. }+ [/ q1 \# T3 s% R8 j" m
, `( C+ h$ \ o8 K4 y" N
else: + ~1 J0 D- J4 c$ |1 j: {% ? if node.left is None: 9 k" T0 [% Q% N child =node.right ; ^/ y6 b; T! u2 W else:# s9 c: X) X1 p- J
if node.left is not None: - D" B. K6 P* `0 a6 _ child=node.left3 U' L. c9 e P7 Q9 F
else:8 F% u# x6 E+ v) e; ` `6 w$ @: B
child=None" @. R; X5 D( Q+ Z5 B
parent=node.parent $ [$ j8 }4 T; k( A5 y5 e. a1 y color=node.color . O% S# j. [; B8 \7 I5 j if child: # A# i$ \* Z' M6 r5 W, _& | child.parent=parent ; H! i% S, M% k) l if parent: ' j- b/ n1 [' v; |# t4 f5 U6 \ if parent.left==node: 7 c; n3 ~8 X2 g2 m6 I+ [+ | parent.left=child % u' [+ [. ^; l n/ Y else:" W. s/ c# @. S( n" P
parent.right=child' d4 Y% R# L6 W5 `
else:. Q+ r% {. s" W# E W8 d5 |7 G
self.root=child : S0 `$ g. f% O% Z/ Y1 D0 o% U& e7 L; H# N( o) ]
if color==BLACK: ! H/ D1 K9 `& e3 K) n; G' R. V8 y4 d1 t* i4 f5 f
self.rb_erase_rebalance(child,parent) 1 T; }4 j6 R; L, q. P, U2 ]$ O `3 Q; s7 u" z) N
; b6 c2 z0 C! j! ^, B X
def rb_travelse(self,node):/ b7 p# I3 k6 a
if node is not None:8 R0 K0 e+ |. W7 T; D; A0 ^
print str(node.data)+'\t'+str(node.color) & _; W, M0 s/ Y$ o2 [, D( Y& } self.rb_travelse(node.left)$ `+ G3 l0 u& ^, u' J$ I3 Z
if node.parent:! {3 I6 N H: C6 h
if node.parent.color==0 and node.color==0: R' ]7 L+ W' k, s
print "error" * g; p, U& i) X return + H, ^# _; F) V self.rb_travelse(node.right)3 _" b% w, E4 t- ~
if node.parent: + _8 ]2 B2 k$ ~, B9 W& t if node.parent.color==0 and node.color==0:4 a ~% r" [% t7 w6 U$ ^+ S2 |, u" s2 H [
print "error"! S! e' [' b% j/ C8 r
return " l/ ?& i/ ~4 |* x4 J' H# J0 k7 X" l6 g6 k1 [2 b
return 0 T; k& k, a3 T, T+ k& N& f 7 \3 k+ ~' f1 I0 e
& H7 s: P) i$ ^. ^9 @/ l def cmp(self,node1,node2): & o G% j7 `# F1 T3 S" k if node1.data>node2.data :2 s2 l# ^9 k6 W& j5 ?
return 18 w0 g4 o/ e2 J* ~
if node1.data==node2.data : 7 P, s4 s0 z# }' ` i" W0 ? return 0% I1 x1 b- l6 M0 `
if node1.data<node2.data: / M% J% f" S4 x S! C" q8 q return -1 + @ @& i" {1 E# k- h * H, N$ |, W. g& T( v [+ Fif __name__=="__main__": % g3 z4 z9 }% U; r( g4 ]* w" Z# ~, T print "main" : @+ |% p7 G U# ~5 ^1 n4 X data=[28,6,39,78,6,43,61,56,71,38] $ H* m' {- H1 u3 X5 ~0 P1 O3 c, m #for i in range(10):4 o2 _1 j) ^5 n& C) z# g
# rand_num = random.randint(0, 100): u6 i) |; T, ^" u% z4 {
# data.append(rand_num)3 x* |- ~- T% o6 L2 i, R6 i
#print data [- ^8 Y. @4 b6 Q& @( {
t=RBtree() - K+ D3 ]8 \; v" u* H! k2 P/ q5 j- y: O
) m3 J7 L8 i* _* e# }/ y for i in range(10):8 s2 }6 u0 ]( k8 }! }
t.rb_insert(data[i])- p/ d _) H: _$ D( p
6 _8 w" {) S$ o9 r
' l" j0 @6 r. Q. ~2 G r+ e t.rb_travelse(t.root); H5 v% L* X8 B' s# s8 }