]% D# b% D9 u/ w, Limport os9 K |4 [7 r0 P& A. K
import random2 g& c- E# U9 ?9 S
# J( R2 R8 z! {RED = 07 C) a: X! g6 |: j9 c
BLACK = 1 , M" W5 s% o9 I3 [* z9 @/ C * {- }/ ~/ _$ d' b4 Q* c& Wclass Vector(object): - h5 D$ I2 ?( h7 Z' Y2 D: b def __init__(self,x=None,y=None): ! |& @( z5 Q. A. s( V self.x=x ) I4 |) ]* d/ Y2 C' a [ self.y=y ) h" i+ v$ b. n1 R4 F8 @3 l" v( L. A, A( R9 q R7 o# i
class Node(object): 5 z4 w8 M& S& s7 [% K8 B" g* { """docstring for Node""" , t: o2 T$ j, `! d. h) k* U4 j def __init__(self,data=None,color=RED,left=None,right=None,parent=None): 5 n1 b- T1 `2 [; L self.data = data4 }' k. w7 M5 }- X( I- _! |% b7 x1 _
self.color = color - [8 V% X4 L4 B! i: ^! Q self.left = left7 ?. U3 R# o, [% c3 X
self.right = right 2 a6 v) M* A: J1 ~4 H o p s self.parent = parent ; Y, v; C U5 _" S( m) o% n9 W& W# q( R; E9 H
class RBtree(object):! a2 U0 Q. N! J8 l. a0 G, T
def __init__(self): / [ {% s! ?" ` self.root=None8 B3 \2 G9 t0 o; T$ Q W- C% p
self.size=0; i$ T/ r8 T: w1 P8 f0 G5 |3 C
6 L7 X1 _9 [& _9 l% z, @6 S def rb_rotate_left(self,node):6 J }0 p' E2 j: I- L( b% x
right=node.right) }! n3 A/ _; `" n
. O( D* W; F- a! x7 g node.right=right.left( V2 j4 ^& b5 T5 z4 k
if node.right is not None: & a" K4 P9 Y# w+ \! S7 r right.left.parent=node: r- h6 J5 N$ S1 ^6 ^: m
! o- W: J/ `: O+ b9 }& }& P$ f: T right.left=node3 u" [: o4 V9 {9 y
right.parent=node.parent y( _; L7 T; Y' s' M4 ~$ Q & I( M2 j3 M( e5 Y if right.parent is None: 3 p; ^ V6 U5 A# G9 v! W0 Y - `" d- r# a5 u. b self.root=right . [* s5 ]$ m; n; L else:" U! r5 a( W& O9 g
if node==node.parent.right: * n, t/ O/ K! \) B node.parent.right=right @2 d% D) g* F! f else:/ k2 c5 q5 d5 y" E5 _0 A
node.parent.left=right 7 M7 b: I1 T# R+ T! H node.parent =right& e6 T- \" y/ ~
, D; ^+ o8 ^/ T. }0 a C2 k" A
9 i6 \8 J: m) n7 L' Q: o
def rb_rotate_right(self,node): - ^6 {, n# [: D, P. C, F# w left=node.left' M# K% z3 o- k; H
node.left=left.right+ ?' E2 ~+ v6 U" g; o1 b1 F
k1 I$ ]$ _4 j* S1 {9 \( ~; u/ E if node.left is not None:) [4 y0 m8 ^$ P
left.right.parent=node 7 M, i: m$ i4 A$ u" H, S) X5 _2 M: \+ ?% F* t9 s
left.right=node 8 V7 B( c! ~4 P& l left.parent=node.parent0 ]: b6 F7 q: W
. L* x+ [3 a1 ?+ g0 x+ s if left.parent is None: 4 w0 C2 y! u: I( G3 F) l. a. Q self.root=left & G% j9 t5 e) ] else: : F& a+ S [5 u! g if node==node.parent.right:5 f6 R% i+ k) d# \
node.parent.right=left ! G3 J$ r0 |( t else:. o% H$ b& t' y5 ]( K; c8 V
node.parent.left=left % w: H/ s4 d6 A) [0 r1 C node.parent=left" E, a4 B& e% {- w) p! _ ^ l, c
! r% S- h" j+ q" N+ c2 ?# r% S def rb_insert_rebalance(self,node):' X8 U/ k; h* _+ D
parent=node.parent! K6 M4 w3 R' I" C# l7 B% Y
while parent and parent.color==RED: ' [0 R/ n e9 ]* L! C9 Y9 i gparent = parent.parent0 r3 W3 w$ W* X# H3 A
if parent==gparent.left: & A" I) Y! V' h$ \& t s uncle=gparent.right4 m8 }" Z% H) g: N
if uncle and uncle.color==RED: 4 E P% z" j' z1 O# u" L" P uncle.color=BLACK! K& B# k) N5 Z! h
parent.color=BLACK 0 K- s5 f# }+ F# M; `" C gparent.color=RED # [/ O0 i# s5 {" W8 e node=gparent ' z& f8 b* i9 K _0 K else: 0 C2 n) W. S( q o if parent.right==node: 9 `! ~; E6 D. J% { self.rb_rotate_left(parent) * F8 S& x! E4 T) j% h+ a tmp=parent/ _% g# C+ t, `3 \& R
parent=node 8 R, ^, N+ G) H, `. Z node=tmp" [6 t4 D8 N8 |3 |& Q
parent.color=BLACK ' {& f+ J( L, {; f/ ^. Y& e& L7 M gparent.color=RED $ q$ f4 g Y( g/ @$ u% T( B. O. @* K7 I$ g
self.rb_rotate_right(gparent)7 x p' x$ V& ? Q* d7 a; S9 N
5 {. U8 X, r2 e L) ?! h! a/ k
if uncle: ) B$ S# s7 k; _ if uncle.right:0 q$ m: u6 g0 ~7 J6 U
node=uncle.right , s9 @. H! N/ v/ q( W/ ]/ E else:1 v" X& L' i4 M" a9 S
uncle=gparent.left : v. U! U6 o( H% f4 \1 B if uncle and uncle.color==RED: 4 I8 F$ l& A+ Y2 g* u uncle.color=BLACK$ L# h/ V! A* u$ P' ~. P% C7 ]
parent.color=BLACK! h% W& A1 K8 V
gparent.color=RED. O! v6 C, o- H
node=gparent 3 |9 c% W" l. k+ x$ z; [/ [ else:" A# O/ N* C# g2 a1 ^) b p+ p
if parent.left==node: $ z1 a# n6 Z" a self.rb_rotate_right(parent) , t0 M# G$ ~$ J! ]3 x; K3 _' g, y tmp=parent4 g& A6 X" `* v3 \5 p3 \
parent=node" d( ?+ c X/ z! Q5 F G* E
node=tmp 3 h1 z% [ |3 q, ^" T M parent.color=BLACK 5 O2 Q2 o9 I2 q* y" K/ |6 b gparent.color=RED / F8 r+ k! T" D& `4 D/ Q self.rb_rotate_left(gparent) 7 d5 {; m$ H3 v7 h& e' z7 _3 w2 Q! H* Z2 P( \' N- ]
if uncle:& {/ K: K7 _; S/ }3 }
if uncle.left:# T7 q* C" M9 S" Q# p% j" n1 Y9 M$ `& X
node=uncle.left5 j W! ?) L, ^/ w( X/ w
parent=node.parent 5 B, l$ _; d( V' `% d- h' E0 O7 c 2 J0 n& u4 }2 V; u2 h5 N; J$ b# ?3 u3 t" Z, b7 B$ @; ]
self.root.color=BLACK 3 U: A/ X' c1 M8 {, K) J! M ; Y2 _( L& l- C8 `" R. g# \! n8 a5 m/ C
8 O3 h6 a# W& e2 z" v3 S8 X p
def rb_search_auxiliary(self,node): , P2 ]$ y% G9 q8 j& g tmp=self.root ! g& o! f0 l% F# ^ parent=None # f" P \" ? U6 ]" C while tmp is not None:& T+ g+ E! l; u+ h; \3 ~; W
parent=tmp, h! L4 C" Q. t9 D7 X, z5 O
cmp=self.cmp(node,tmp) H/ \8 G7 v; f
if cmp<0: : {" T4 x9 ` H% J* x7 C tmp=tmp.left6 E! j6 j! {0 {+ g7 X0 W- Y3 ]
else:0 w- a4 r: Z/ z$ e9 s( q% j1 O$ M
if cmp>0:9 w* t7 t* D( s
tmp=tmp.right3 d# S& {- j6 l/ g3 I9 |( `4 ]
else: : j/ Z+ V v3 P: t( d% z return tmp,parent 3 {; x$ q) F3 D+ t 4 ~8 A) Z. u1 q/ d! K) Y% e7 ` return None,parent - A" H5 V4 f% J6 W' i3 M z) m5 T3 ^& U' [- ~* ^* m6 K! Z0 d( [; t
def rb_insert(self,data): x" I% g) ~) b! D( S: o( H% E8 a. ?
tmp=None. a/ G* W6 A7 R8 Q& K
node=Node(data)4 J |% b) q- `7 {# N
tmp,parent=self.rb_search_auxiliary(node) ; X0 [/ z+ l7 L/ |& E4 r2 t% R9 R/ c3 y( _2 k0 O
if tmp is not None: / B. ] b& N) L- C: T- } return & P/ [/ ^2 X4 Z( N" U! \6 u8 m
* z5 V' m# }8 V
node.parent =parent 5 N/ \( _0 A' R) G- q7 X9 c5 K) Z node.left=node.right=None ) j7 F+ a# t( r. o6 N node.color=RED ! ^. `2 \: R( r8 D' `# U: w) Y# x. F+ ]0 w9 f) k9 L
if parent is not None:2 U: q5 |0 @) }3 F
% P9 O% m* _8 d, q' ` if self.cmp(parent,node)>0:! E8 {( g S; m1 k0 J% G0 a0 V
parent.left=node1 R8 X$ ~2 a7 p& e0 i5 o
else: 7 r( u& B9 e* ^) A" l* \ parent.right=node) R) k, o2 q9 c5 P# O
else: ! g' e. k K h% l1 I7 ?5 ` self.root=node ' Z& ^9 O: a) H/ J return self.rb_insert_rebalance(node): O% D5 k5 M+ R A4 d4 o$ \
|- e* u! A" I* M1 D def rb_erase_rebalance(self,node,parent): a! m( H& o% ]7 s! H; P, P
while((node is None or node.color==BLACK)and node !=self.root): % h$ I/ P! D: j: w; e! T if parent.left==node: 7 a0 i* u( ^' {( N: `! I9 j other=parent.right 6 L) c1 z* L# E# }2 p8 N& e* x% z if other.color==RED: , ~5 r3 [5 s1 }/ ?( ? other.color=BALCK; U p! ^( R7 r
parent.color=RED% ^+ T' K4 ~) k/ b/ h
self.rb_rotate_left(parent)) h2 @; z K6 L/ q; j
other=parent.right * A4 Y8 j0 G! t' p+ ]2 X if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color ==BLACK): & H _" J+ A# ]) G other.color=RED 1 V/ X1 V# r" }: y# u$ Q+ b' j3 k node=parent 6 A9 A( D8 `4 A# ~0 S+ {& M parent=node.parent * Q: { V; l; I- O, ^( v* W else: 3 [1 J% U; {- ?& p, w7 R if other.right is None or other.right.color==BLACK: # `) w" u3 n- K& l1 l: X$ B" _" U% x3 B# s" g; C" a$ a( X- Y
if other.left is not None: & E& R+ ?, j j other.left.color=BLACK & h3 T" D7 o0 A other.color=RED 1 h: g- E' l% b) Y" j- |* Z self.rb_rotate_right(other) 0 [+ {! w6 l4 l9 w other=parent.right( j6 k) ]' N: j
$ w1 P9 z3 ~. M- |: u. |( H, H4 r
other.color=parent.color 2 O7 x/ M) P. D parent.color=BLACK+ x2 n/ I: q, G) T/ _
if other.right is not None:' |8 ]5 f) ]4 a- u' c: c
other.right.color=BLACK* V9 n. h: [" Y
self.rb_rotate_left(parent) ( _1 n# d1 X4 j5 d/ I) \. ^ node=self.root 7 f z% O2 x9 X" K& y( |( v9 r break' s6 j! G( I- f( {0 ~/ e# T
else: ' ^1 C' V: c3 {# s6 \! L' Z9 d other=parent.left $ z4 q- C: Q: M, o5 U4 k* R if other.color==RED:3 n% C5 t' f0 N. U( ~1 Z8 ^
other.color=BLACK& M9 B' E6 @6 c7 |( z& Z! J
parent.color=RED : `, p( z$ g1 R X' h& J* ^ self.rb_rotate_right(parent) T ^7 x2 r* F4 V4 o3 r
other=parent.left , H! ~0 b! c. k$ L4 I if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color==BLACK):4 j" u$ `6 s0 H+ L9 `. E! t% V# k
other.color=RED! c$ g1 u$ @; u4 ?7 {# W9 k' v
node=parent$ d' i. e. v: Q# y% r7 H
parent=node.parent " j, G. s, N+ o9 k+ \/ D. m else: 7 {# ^; V& z. x3 \/ M" O/ H if other.left is None or other.left.color==BLACK: 0 X9 e) g7 h# g& a5 x, B if other.right is not None: 5 H; ]+ V q+ Y, \, t9 K other.right.color=BLACK # G8 Y `& N: Y+ }" w5 L9 x! @; f4 p( S1 d r; @
other.color=RED1 e0 {& _4 n" c
self.rb_rotate_left(other)* ?: P ~ V3 s! p" r7 P+ b7 [! ~ o
other=parent.left, L, W/ r6 ?3 c* y: q% q! q8 S
: X* {4 K2 ~# o7 o other.color=parent.color : m; L' @, Z, [; o! o s7 |3 t parent.color=BLACK # C; `" Z O6 t2 A! q2 @8 z' [0 X2 t. S; \( [% _+ e: B6 K1 G
if other.left is not None: ( {4 e' D; q- S( Z other.left.color=BLACK1 M7 @0 C% @- {$ e, c- Y
- x. P7 C M$ L2 O |0 ` self.rb_rotate_right(parent)4 X* @4 Z8 h @( v6 Z/ _& {6 m% l
node=self.root ; o( P7 F# i" R u( L* T break4 ~; T/ [ R& b6 z. K) b9 |
# R1 W$ k& p y7 t9 r/ u 0 k( ?* j% L0 `( G8 v1 E4 P$ o `4 p X
if node is not None:# k1 v) X- {# i
node.color=BLACK 9 ^2 P% I7 O8 f( D/ `% [! x) D" d0 K7 B: R' D
def rb_erase(self,data): - i% n' l" \- j7 F b6 i tmp_node=Node(data); R* `5 x4 a4 K$ P* O% O
node,parent = self.rb_search_auxiliary(tmp_node) , B/ j' h- B& R2 F3 B7 F% `" d if node is None: & ]1 f9 w0 C$ x& d9 |; b. N O print "data is not exist."5 _# f# g- T1 T) k& W I
return 6 p- i# Y3 o2 G9 m# K & E/ ~& R% x1 Q2 _' g old =node4 L) ~/ _. w4 S3 F+ |$ u
if node.left and node.right:4 ]5 ?& A& j" b' D
node=node.right, A: {; b. ^& @- M! `8 `: R
) G' X9 ]9 z% o0 }9 z left=node.left ( w- j& X7 R. L% B! j k$ h while left is not None: 4 X/ O& \3 o+ O& b node =left 0 ]" E: p' T6 y) f1 t5 J% Z$ K left=node.left . ]. D3 U& r Q M E$ E0 J' P! Q- p% `. u/ J6 f
child=node.right3 Y) d4 q' C2 g8 ?$ p% j! C* ?& P
parent=node.parent7 u7 N* @. `$ i
color=node.color" F! b( A: V0 d, E0 {) o" l: A
: w3 P$ E+ S. C3 B' G if child: 7 s& u; w' o( g. G% y) I" t child.parent=parent# x5 I, H) B( G- H) A$ M
if parent:/ G% ?+ A. G' D1 r8 |( U+ D
if parent.left==node:8 H1 v' D6 }' e# w; ~. o
parent.left=child S7 d# i0 m0 |! S else:# |; p7 m6 `5 N! H% F9 `6 Q# e r
parent.right=child $ q; B2 i2 L& V+ c! B9 r& t. G& b2 k# T" `% h1 N" Q! e
else: & S5 N/ s; Y) V; t! J* ]1 o% \6 X" x8 F self.root=child1 C, g; X' ^4 w- ^0 K
1 J2 _' y. s! G* U6 a
if node.parent==old:; T+ B2 e: E$ ^) u% l" w1 h
parent=node $ {8 H. i* b& b ]1 d- V# b node.parent=old.parent 7 ^+ p& G* l% H1 h% R& F ^ node.color=old.color 0 r' x" s" \" u$ V8 q- ? node.right=old.right- J% P7 t$ U* o
node.left=old.left9 Q A9 L+ P$ |) O" M* w7 s" C7 x2 w; ^
/ h* U6 [* `9 h- {9 P5 k if old.parent: 9 j9 Q! |' Q4 }7 z if old.parent.left==old: ) I, V, l$ t* A% G6 r: q8 {( ? old.parent.left=node" F9 Z, y5 Q8 A8 ?) P0 U* y' s$ o
else: ( c* l8 |7 B* J/ C8 u old.parent.right=node/ S% h6 ~2 _# t) ~
else:% d& r# _2 k! E' J4 w( Z r# R
self.root=node* H) j/ p: [, A) ~1 {
. H# f2 R) b; K& { old.left.parent=node " i" z r3 x7 M if old.right: 3 J/ j2 ]3 H6 V2 p7 c old.right.parent=node 5 p" i4 a! \" H& n 2 }" P. [# E7 m7 m7 l! v else: " j/ n j7 s' r$ v3 m if node.left is None: ' g; K2 ~. Z6 Q/ x; b% H# z) E9 S child =node.right % q" ]7 S5 O E$ [3 f else:0 _; P0 l; t3 A% j- K. A* O
if node.left is not None: # @ U; g- `5 |, J* A) H. q child=node.left $ f1 v/ h; R% d& E! n8 c. c else:) K3 }- a" |( Y. H, V. A9 u- E6 P( u
child=None4 I7 t7 w. l: `
parent=node.parent4 _( D1 Y2 R5 Q# X: B3 I6 d
color=node.color% n* v& n- w4 y1 X
if child:8 G6 O& U+ V) Y) T8 q. W. i
child.parent=parent2 D, c4 K6 `; }6 _
if parent: ( Q G1 j4 A! `- p7 O3 A if parent.left==node: 7 N" R& n" P/ A; `' r; V. O parent.left=child ( a5 t! ~, I: S& t else: 8 h& x+ j# y% Z7 z8 A% Y parent.right=child - S1 Z! z5 t5 L else:+ k2 b Y# o) O% A% a# U6 D
self.root=child* _' A9 F& s6 \0 D+ Z# {
! g* c: O! W6 E3 ` if color==BLACK:5 y! J* a' C7 z8 v! a
# m/ e$ Z* W% s9 L( h7 i' W
self.rb_erase_rebalance(child,parent)+ u6 h$ i3 @3 A+ P1 V
4 I* y. f! S% d# z# |8 m
, R0 G9 w e: _( v" [: k
def rb_travelse(self,node):% ]: O5 V2 i3 e4 i# R1 G1 b2 E
if node is not None:* c/ C& w/ w. f4 u b
print str(node.data)+'\t'+str(node.color) : R* q, \# D& X! H# r0 o: Z7 A self.rb_travelse(node.left)! A7 h' P4 c1 V1 N$ [, F2 \4 J; c
if node.parent:; Q. E3 B7 Z; A0 |8 q# r( z7 d1 T
if node.parent.color==0 and node.color==0: 0 V9 f6 w" Y2 ^6 f+ U7 `. U print "error"- k# L. X' t/ S% S ^. M
return 2 F% O( Y1 _& R3 B- X& i- [ self.rb_travelse(node.right) " O1 N6 W" b. F9 Q% o' E/ k if node.parent: . a% T) l# B6 F6 }' |' O if node.parent.color==0 and node.color==0: 2 |8 |6 s/ R, k* u9 v/ T- t print "error"" Z) V7 i& ?5 g0 |
return, e. V) j) H3 h5 {
# r: ^" x- Z0 b; o( u return: g! l# T5 d; W. |; B
( v5 n' U- }+ J9 P- O1 |/ [* M3 ^! o $ e1 W& | I, Z. q# G
def cmp(self,node1,node2): 3 p ?1 t# j& q2 ]& Q7 w3 U if node1.data>node2.data : . Z, S. }& z- ^/ M! e$ u) L* l* E return 1 - C, O B. W* ?5 Q2 H6 D if node1.data==node2.data :/ l9 ~1 L5 t5 z; o. {1 L
return 0: c7 F' ~. J2 T- B$ h
if node1.data<node2.data:7 }; l6 F' Q6 f3 a
return -1) t' d4 m1 n& K# ]
4 a m; U* N; N6 M9 ^0 ?- Rif __name__=="__main__": : c) I s9 S: \- A0 m7 P9 \ print "main" R6 M* n+ I8 @$ x
data=[28,6,39,78,6,43,61,56,71,38]! ?) M6 u& r+ I# N
#for i in range(10):- @; c v8 F) C9 |2 v% m
# rand_num = random.randint(0, 100) / M1 G9 h k5 J$ D # data.append(rand_num): C! d( l$ }3 p5 Q9 v3 w8 K' ^1 Z
#print data$ r N% {+ W( B; d5 u8 W, d
t=RBtree()5 z7 o2 p$ t2 w: w8 I$ A
3 k/ R7 a# G& w% m0 L5 R' r3 ~% q
! H) D0 {% f! y: g }$ K7 w5 I W1 h* I5 n
for i in range(10):" i+ g! x. ]% d6 i
t.rb_insert(data[i]): _4 A% Q+ N8 R
/ u+ \, f/ b: L 3 h, f, ?# {# ?: m t.rb_travelse(t.root)0 [7 W8 I& S4 V. C* I
, o% U( B' D( |- I4 b% R
print "---------------------------------" , D2 ^1 K8 |+ ]3 g, E t.rb_erase(data[7])7 R3 p' t/ R1 Y {) _