% E% H. T% l8 N def rb_search_auxiliary(self,node):* G" v) C6 e: _, }5 N
tmp=self.root% ?" k$ n z3 J4 d
parent=None q& r* [# h: e2 U% [
while tmp is not None:& H/ r8 T$ b6 h' Z; D1 a' q
parent=tmp 8 _5 M T6 ?8 @3 R8 C; O' E7 T cmp=self.cmp(node,tmp)3 }3 c% r) F6 a4 C6 ]: |- |
if cmp<0: ( c6 g0 K5 D6 b" F% j tmp=tmp.left8 ^5 ]4 E$ g: ]6 f
else: - J; J( r# J! ]& F, } if cmp>0:) Q5 X% R, X) }; w) u7 |! C
tmp=tmp.right : b) h. f. @- t+ Z6 I8 [, [0 C' G, } else: 8 B$ _2 |6 w9 J' }. U return tmp,parent 3 G; J) n6 b3 l( y # B) t4 ?4 V7 U! z& Q3 ^2 S return None,parent 6 B# d& X2 T. Y2 Y2 ~2 ]8 D* }" Z+ E4 k, `- [' F+ G: h, M
def rb_insert(self,data): f; U# b' }, T" x% [0 e
tmp=None" U- R: u8 L" B
node=Node(data)9 y$ l& `9 R' O. z3 E/ d0 O+ t* W
tmp,parent=self.rb_search_auxiliary(node); E. f( t% N0 S. C1 w4 h% c& a
7 v' F+ d- t: E( c if tmp is not None:+ F" Y% B1 T3 U- n
return + H% k$ N1 ?' X* Q1 [9 z
2 z$ P$ Z# @4 i! y F$ J9 g0 d node.parent =parent + D. o2 I* Y9 Q0 m node.left=node.right=None4 K0 x2 M8 o/ w( u' I V
node.color=RED 2 m* }0 m. o4 l$ U- f6 r7 Q7 f1 o- @: P: U
if parent is not None: 0 g; B8 a4 w" s! k* ?) P& x+ `5 c) ?
if self.cmp(parent,node)>0: & R( j* K$ c- |' K parent.left=node " P! R4 V7 J; k. f else: v: Q8 y7 b6 b& Q' a, \; I; }0 F9 @ parent.right=node 1 `+ M) J1 Z+ T! v, ]1 h else: 1 Q) j% ?, `5 M5 Q self.root=node+ l% I+ s/ R4 s- H# ]' i+ d
return self.rb_insert_rebalance(node) 5 Q( x* H8 \7 o$ L+ v 9 g+ x% _0 x& g# l) ] def rb_erase_rebalance(self,node,parent):- k, p- u! W1 ^8 k: `
while((node is None or node.color==BLACK)and node !=self.root):3 `* A" s, c; G7 h) p
if parent.left==node:% t8 Q9 B2 J% r& c$ |/ d4 i! L* n3 O
other=parent.right1 b, v9 m# t5 U0 L8 c k6 l$ h+ j
if other.color==RED: + x$ F* w5 i& h9 [; U" y/ _0 x other.color=BALCK # x* D' w6 D5 y8 v' ]1 `/ k& m parent.color=RED& F" \) b) _& H' _* I) W
self.rb_rotate_left(parent) & @' X7 T# u7 H8 o other=parent.right7 U1 l! R) [- |2 X8 n( ]& u/ ?
if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color ==BLACK):5 [) ?. ^ z/ P& G
other.color=RED: D5 j# I1 j: R- v
node=parent - }$ `# o, H. M' x parent=node.parent ( m4 n' A/ ?0 A else: 0 D; o; D$ c% ~ j$ d1 X if other.right is None or other.right.color==BLACK: 0 i/ _( f- L4 F- R( D; _: {: A5 u/ p" s' Y ]
if other.left is not None:' _8 d3 E& c4 t9 D1 w% y$ Y
other.left.color=BLACK! J/ A' y/ q1 R
other.color=RED4 E0 ~7 M5 Z* W: U
self.rb_rotate_right(other)7 d6 B V" f6 @( L6 y* P
other=parent.right8 X# G2 y; I* f+ w/ n3 I9 c9 B; J
* L+ M: g) h/ I+ b3 a other.color=parent.color J$ N4 _4 U) {! K/ F parent.color=BLACK ; E+ h8 t( V. V& E( }7 j" u if other.right is not None: * _3 _% w! w5 @+ n- A other.right.color=BLACK 9 b; S- d# g- ~; _3 w) b self.rb_rotate_left(parent)' L5 V. W" H3 k
node=self.root 1 i. ^8 l% H k: s7 x( v break* n9 ~* ~- d1 D& F
else: n# q5 H. [; j$ e
other=parent.left ( s+ I6 o. g p' o$ | if other.color==RED:% a7 @- ]/ D9 R( J4 D. d
other.color=BLACK& [ `- ]7 \8 m$ S( m# B
parent.color=RED; z. X# v0 |' t0 B- o
self.rb_rotate_right(parent) 2 `' r8 v1 B! B( e; X r. M z other=parent.left , o k+ q% \: \5 c0 `& f% G if (other.left is None or other.left.color==BLACK) and (other.right is None or other.right.color==BLACK): 8 R* o: [8 H+ P' M2 i7 ^ other.color=RED, S: U$ g4 q# q3 q7 j
node=parent9 H0 t+ j* p1 Z; d
parent=node.parent 6 Z2 e; I% _3 E else:8 X! r7 y- c7 @" T0 ]
if other.left is None or other.left.color==BLACK: , _* S2 t7 @5 ]7 ~3 R if other.right is not None: ; b: l: v! ~6 E+ C( ^7 v/ s other.right.color=BLACK' G0 n6 f) U" X/ Q; m3 d* z
2 y0 z! G9 h: n& w+ N
other.color=RED" Q( F/ W8 ~1 N
self.rb_rotate_left(other)/ D$ }2 j2 L! A4 g4 J/ i1 h
other=parent.left - P9 i! b) v3 V5 X2 I ; @, |4 t8 Z. Z- D" u) Q other.color=parent.color3 T$ l5 o5 L3 h6 ~+ d( J! ]1 Z
parent.color=BLACK/ A5 F" R4 d; d2 v3 l
0 @3 _) z$ F$ b0 G: K/ [! u
if other.left is not None: ) R3 K) Z( Q7 V o other.left.color=BLACK 0 M0 \' m K6 R 1 x N% A# Y1 R. s6 l5 M) v self.rb_rotate_right(parent) p' T, L- G; J5 u6 e node=self.root 0 ~1 W( k: ^5 y! }. ~1 ~4 E break , X; y1 o) \$ | ; i& U9 A+ m/ X) t0 L 4 E8 D6 D' K8 l; } 3 {- z" t6 [! Z e S if node is not None: 5 U ]* T: \% H4 K o7 c/ d node.color=BLACK . y& @, B% b g) \0 g' g$ o4 s! D# d" ~2 m( A1 m3 J! r& m( w
def rb_erase(self,data):1 y* C1 N) \4 }
tmp_node=Node(data) ; b \. V& {0 e' [; h node,parent = self.rb_search_auxiliary(tmp_node)8 b. l( e/ m9 Q6 D! S
if node is None: ) D( x4 U9 g8 ^7 _ print "data is not exist.". R6 G1 z! \& q6 _, R
return 7 ?: G8 i/ h5 U Z8 {9 { 7 a2 _, @+ g) ?% Y' e3 d old =node. Y( |' \) R' E! \; D$ k$ w% {0 F4 k+ R
if node.left and node.right:% X% j) b" `7 v. t* v
node=node.right5 X# w4 J( X w; o8 I- d2 L5 ~
5 o. Z, b: E* i% Y
left=node.left$ S0 A9 R# D! A6 x$ k/ x* a( \
while left is not None:9 ^( Z2 R7 f8 o8 V: K4 W1 \
node =left 4 b, `* M8 U! X% `0 E left=node.left ) y2 u! J$ p4 ~5 k) ] # D4 e- q+ q/ K7 | child=node.right7 X7 C4 F* x) C3 p8 t
parent=node.parent. n6 @- W8 E" q+ C' N# f+ l
color=node.color. W: m% J$ U ~1 ^# T4 `* A# d
2 Z' N& z" F+ \! \7 Y! K if child: * n6 m. A. n3 x! p child.parent=parent3 g4 c7 T5 I& P+ E
if parent: / K1 N% m; C& j# B4 \, ^8 A3 `1 u if parent.left==node:( Z `# y+ P: w) R
parent.left=child ( v7 x& O B# j( i4 f else:! {0 f2 U8 N9 V/ \6 C" B
parent.right=child4 H- S4 p) p' I
" N; z8 f2 I' d: r+ x5 x1 x else: . L A6 V* C. a- G7 y" d self.root=child3 T1 L4 x/ c6 D7 H- r5 t6 W
' I2 y6 y7 e/ ^
if node.parent==old:: G; Z% a$ O; @% v' Z5 Y) I+ m
parent=node9 E% ^. E& R5 {9 d1 u5 K
node.parent=old.parent 9 H2 N" d/ s; l* w6 R) Y. @7 X node.color=old.color3 w' G/ `& v; a) c
node.right=old.right 0 Y6 n, \% t+ D+ h1 d% n node.left=old.left + `0 W, g- R( d: s8 g" j+ { 8 j! Y6 t% {7 n9 S% z, ~$ [ if old.parent:( H% A9 y9 S# a( Y& G( b9 j, B
if old.parent.left==old: ! `8 V5 C0 s& k# ^4 ], d old.parent.left=node ' `" S, ]1 n. q2 n. [( k ? else:4 k' m# w0 k O8 q! N* o
old.parent.right=node 1 w5 A) c; F: x! ~7 h else:0 u% F: |" a" g; @/ R3 B
self.root=node$ @: O% s9 Z0 c$ E5 u
; h+ t% `3 r5 Q8 H6 v# A# `: O
old.left.parent=node9 V" V0 `8 S2 H1 v/ W& G U
if old.right:! B9 x8 Q2 ?- D6 e* o
old.right.parent=node! J' Q m; [8 }; L
4 E* I9 c6 V3 Z. r
else:, j) @2 \" U( K X4 [0 x2 _
if node.left is None:/ L0 q; N1 \0 a
child =node.right* j5 m+ _: L1 [# e# E, V
else:6 H5 q- c' B; x7 z U
if node.left is not None:, w) c$ b/ A! M
child=node.left, E4 ]0 i0 e6 A3 \, ]4 I
else:, O$ F2 h4 l/ _' u5 r1 d6 z1 ^
child=None% u0 q9 F# h7 r. C
parent=node.parent+ x! D" i% j3 r$ E
color=node.color , i) ?1 w8 R+ S1 ^ A6 w if child: 8 A3 g; Z# `' d child.parent=parent- q7 g: h( A+ {8 S' e4 \9 h
if parent:5 h% v) N) m2 F0 G- h& r
if parent.left==node: ! w- |+ [* w8 d& I5 [ parent.left=child . J3 }/ j) A; k2 v7 z else: o( e4 } z' ^* s( G9 A# o
parent.right=child5 u3 s9 [* a5 b9 b
else: * h! h1 y7 L7 I9 E self.root=child, w2 f! A" T5 I
7 a) N: O8 h3 x if color==BLACK: 4 E' W1 ^+ X0 M1 H , d" |# \! C& Q k9 b+ a self.rb_erase_rebalance(child,parent)8 V, g) R8 G$ B" A2 D# a# G2 c
5 V7 M: r, {3 O; F, J6 T+ b8 [. q
" U! J1 U2 f6 g/ P, | W8 n7 A def rb_travelse(self,node):/ B }9 ?' R& I' a& Z$ A- Q, J
if node is not None:& G% O4 Z. `, |3 P; {
print str(node.data)+'\t'+str(node.color) - y. z& K2 ^7 e2 t5 _, H* M4 W# [ self.rb_travelse(node.left) b3 X! a* O" }% U" K6 B5 g7 C if node.parent:9 p) O+ b3 O5 w; G( \
if node.parent.color==0 and node.color==0:6 X h# f p# V* v. b
print "error" 8 {4 i$ z4 j# y: A return8 j4 j$ k2 c2 S$ M' s$ k* H
self.rb_travelse(node.right) $ M5 L2 t$ H% O if node.parent: 0 R. n( A, a. j! D+ X* J' S" f* m& C if node.parent.color==0 and node.color==0: % }8 I8 \# s1 l print "error" & w8 N3 d1 r8 |* j return ( b4 u/ }. x$ k$ }6 t& d * k, {5 I, S) p& C return6 {- H' H. M6 o* ^4 V
1 l( E$ L! ~. q9 B, y
8 K* v9 x8 l. ^+ Z def cmp(self,node1,node2): , P: }: W5 }7 M% I( e9 b: |7 }) | if node1.data>node2.data : 9 E; b. f( u6 w) Y return 1: }3 ~( G K0 H/ x7 j; R5 a
if node1.data==node2.data : ) e2 i% d- J% p return 0$ q2 K' J4 P$ D! ~! y/ {
if node1.data<node2.data: 1 U% U+ V, d6 V9 E- e$ q# U return -1 5 Q4 E4 S! V/ K8 m7 B3 u : b4 R5 I; g4 `! c% b. D5 mif __name__=="__main__": * U. G% M$ p1 R5 E2 D, A% Q print "main" ' X$ g& `: j0 m8 a1 ]' F4 _* q data=[28,6,39,78,6,43,61,56,71,38]" U' k: v4 t, x' Z% q$ R0 |/ v
#for i in range(10): & V) Q' v) f; r # rand_num = random.randint(0, 100) - c1 o6 c- g3 {4 J& \ # data.append(rand_num) 3 t! _% N! ]' f( o+ T #print data$ U, Z! v+ M# K* _2 V
t=RBtree(): d5 ]7 O& V9 B# ^ D3 ~
+ M% Q1 g; t: y* h1 C$ s 4 C7 M ? G! q! e+ G# ^ for i in range(10):; w% `' T6 L6 R: M
t.rb_insert(data[i])! S. n; ^% x) o, \+ C
; D5 a1 H6 X9 l' F* r3 U9 r& P" S& E- K& r
t.rb_travelse(t.root)" F, q% d( c$ G5 q& C
: A9 }# }% @. l- _- _
print "---------------------------------"2 \+ p- f. l; [( q! w
t.rb_erase(data[7]) # V, B- i9 i3 H: F, ]8 n; \ 3 K9 {0 {3 r& i- V. o$ e
t.rb_travelse(t.root) 7 c: R7 h6 d% M# l0 j' _0 Q9 s/ q; r- h% P& q8 A4 Y