Docsity
Docsity

Prepare-se para as provas
Prepare-se para as provas

Estude fácil! Tem muito documento disponível na Docsity


Ganhe pontos para baixar
Ganhe pontos para baixar

Ganhe pontos ajudando outros esrudantes ou compre um plano Premium


Guias e Dicas
Guias e Dicas


Capítulo 43 - Árboles Rojo-Negro - Liang-Java-Comp11e, Notas de estudo de Informática

Árboles Rojo-Negro

Tipologia: Notas de estudo

2018

Compartilhado em 21/07/2018

dddmmm80-5
dddmmm80-5 🇧🇷

4.8

(4)

13 documentos

1 / 30

Toggle sidebar

Esta página não é visível na pré-visualização

Não perca as partes importantes!

bg1
Objectives
To know what a red-black tree is (§43.1).
To convert a red-black tree to a 2–4 tree and vice versa (§43.2).
To design the RBTree class that extends the BST class (§43.3).
To insert an element in a red-black tree and resolve the double-red
violation if necessary (§43.4).
To delete an element from a red-black tree and resolve the double-black
problem if necessary (§43.5).
To implement and test the RBTree class (§§43.6–43.7).
To compare the performance of AVL trees, 2–4 trees, and RBTree
(§43.8).
Red-Black Trees
CHAPTER
43
M43_LIAN0182_11_SE_C43.indd 1 5/29/17 10:31 AM
© 2018 Pearson Education, Inc., Hoboken, NJ. All rights reserved.
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e

Pré-visualização parcial do texto

Baixe Capítulo 43 - Árboles Rojo-Negro - Liang-Java-Comp11e e outras Notas de estudo em PDF para Informática, somente na Docsity!

Objectives

■ ■ To know what a red-black tree is (§43.1).

■ ■ To convert a red-black tree to a 2–4 tree and vice versa (§43.2).

■ ■ To design the RBTree class that extends the BST class (§43.3).

■ ■ To insert an element in a red-black tree and resolve the double-red

violation if necessary (§43.4).

■ ■ To delete an element from a red-black tree and resolve the double-black

problem if necessary (§43.5).

■ ■ To implement and test the RBTree class (§§43.6–43.7).

■ ■ To compare the performance of AVL trees, 2–4 trees, and RBTree

Red-Black Trees

CHAPTER

43-2 Chapter 43 Red-Black Trees

43.1 Introduction

A red-black tree is a balanced binary search tree derived from a 2–4 tree. A red-black

tree corresponds to a 2-4 tree.

Each node in a red-black tree has a color attribute red or black, as shown in Figure 43.1(a).

A node is called external if its left or right subtree is empty. Note that a leaf node is exter-

nal, but an external node is not necessarily a leaf node. For example, node 25 is external,

but it is not a leaf. The black depth of a node is defined as the number of black nodes in a

path from the node to the root. For example, the black depth of node 25 is 2 , and that of

node 27 is 2.

Note The red nodes appear in blue in the text.

A red-black tree has the following properties:

1. The root is black.

2. Two adjacent nodes cannot be both red.

3. All external nodes have the same black depth.

The red-black tree in Figure 43.1(a) satisfies all three properties. A red-black tree can be

converted to a 2-4 tree, and vice versa. Figure 43.1(b) shows an equivalent 2-4 tree for the

red-black tree in Figure 43.1(a).

Figure 43.1 A red-black tree can be represented using a 2-4 tree, and vice versa.

20

(^15 )

3 16 25

27

50 15 20 34

3 16 25 27^50

(a) A red-black tree (b) A 2-4 tree

Point

Key

43.2 Conversion between Red-Black Trees

and 2-4 Trees

This section discusses the correspondence between a red-black tree and a 2-4 tree.

You can design insertion and deletion algorithms for red-black trees without having knowledge

of 2-4 trees. However, the correspondence between red-black trees and 2-4 trees provides use-

ful intuition about the structure of red-black trees and operations. For this reason, this section

discusses the correspondence between these two types of trees.

To convert a red-black tree to a 2-4 tree, simply merge every red node with its parent to

create a 3-node or a 4-node. For example, the red nodes 15 and 34 are merged to their parent

to create a 4-node, and the red node 27 is merged to its parent to create a 3-node, as shown in

Figure 43.1(b).

Point

Key

43-4 Chapter 43 Red-Black Trees

You can prove the conversion results in a red-black tree that satisfies all three properties.

Property 1. The root is black.

Proof: If the root of a 2-4 tree is a 2-node, the root of the red-black tree is black.

If the root of a 2-4 tree is a 3-node or 4-node, the transformation produces a black

parent at the root.

Property 2. Two adjacent nodes cannot be both red.

Proof: Since the parent of a red node is always black, no two adjacent nodes can

be both red.

Property 3. All external nodes have the same black depth.

Proof: When you covert a node in a 2-4 tree to red-black tree nodes, you get one

black node and zero, one, or two red nodes as its children, depending on whether

the original node is a 2-, 3-, or 4-node. Only a leaf 2-4 node may produce external

red-black nodes. Since a 2-4 tree is perfectly balanced, the number of black nodes

in any path from the root to an external node is the same.

43.2.1 What is a red-black tree? What is an external node? What is black depth? 43.2.2 Describe the properties of a red-black tree. 43.2.3 How do you convert a red-black tree to a 2-4 tree? Is the conversion unique? 43.2.4 How do you convert a 2-4 tree to a red-black tree? Is the conversion unique?

43.3 Designing Classes for Red-Black Trees

A red-black tree designs a class for a red-black tree.

A red-black tree is a binary search tree. So, you can define the RBTree class to extend the BST

class, as shown in Figure 43.4. The BST and TreeNode classes are defined in §26.2.5.

Each node in a red-black tree has a color property. Because the color is either red or black,

it is efficient to use the boolean type to denote it. The RBTreeNode class can be defined to

extend BST.TreeNode with the color property. For convenience, we also provide the methods

for checking the color and setting a new color. Note that TreeNode is defined as a static inner

class in BST. RBTreeNode will be defined as a static inner class in RBTree. Note that BSTNode

contains the data fields element , left , and right , which are inherited in RBTreeNode. So,

RBTreeNode contains four data fields, as pictured in Figure 43.5.

Point

Check

Point

Key

Figure 43.4 The RBTree class extends BST with new implementations for the insert and delete methods.

1 Link

RBTreeNode

–red: boolean

+RBTreeNode() +RBTreeNode(e: E) +isRed(): boolean +isBlack(): boolean +setRed(): void +setBlack(): void

TreeNode

+RBTree() +RBTree(objects: E[]) #createNewNode(): RBTreeNode +insert(o: E): boolean +delete(o: E): boolean

RBTree

BST

m 0 Creates a default red-black tree. Creates an RBTree from an array of objects. Override this method to create an RBTreeNode. Returns true if the element is added successfully. Returns true if the element is removed from the tree successfully.

43.4 Overriding the insert Method 43-

In the BST class, the createNewNode() method creates a TreeNode object. This method

is overridden in the RBTree class to create an RBTreeNode. Note the return type of the

createNewNode() method in the BST class is TreeNode , but the return type of the creat-

eNewNode() method in RBTree class is RBTreeNode. This is fine, since RBTreeNode is a

subtype of TreeNode.

Searching an element in a red-black tree is the same as searching in a regular binary search

tree. So, the search method defined in the BST class also works for RBTree.

The insert and delete methods are overridden to insert and delete an element and per-

form operations for coloring and restructuring if necessary to ensure that the three properties

of the red-black tree are satisfied.

Pedagogical Note Run from http://liveexample.pearsoncmg.com/dsanimation/ RBTree.html to see how a red-black tree works, as shown in Figure 43.6.

F igure 43.6 The animation tool enables you to insert, delete, and search elements in a red-black

tree visually.

43.4 Overriding the insert Method

This section discusses how to insert an element to red-black tree.

A new element is always inserted as a leaf node. If the new node is the root, color it black.

Otherwise, color it red. If the parent of the new node is red, it violates Property 2 of the red-

black tree. We call this a double-red violation.

Let u denote the new node inserted, v the parent of u , w the parent of v , and x the sibling

of v. To fix the double-red violation, consider two cases:

Case 1: x is black or x is null. There are four possible configurations for u , v , w , and x , as shown

in Figures 43.7(a), 43.8(a), 43.9(a), and 43.10(a). In this case, u , v , and w form a 4-node in

the corresponding 2-4 tree, as shown in Figures 43.7(c), 43.8(c), 43.9(c), and 43.10(c), but

are represented incorrectly in the red-black tree. To correct this error, restructure and recolor

three nodes u , v , and w , as shown in Figures 43.7(b), 43.8(b), 43.9(b), and 43.10(b). Note x ,

y 1 , y 2 , and y 3 may be null.

Point

Key

Figure 43.5 An RBTreeNode contains data fields element , red , left , and right.

node: RBTreeNode #element: E -red: boolean #left: TreeNode #right: TreeNode

43.4 Overriding the insert Method 43-

in Figure 43.11(a). After recoloring, the nodes are shown in Figure 43.12(c). Now w is red,

if w ’s parent is black, the double-red violation is fixed. Otherwise, a new double-red violation

occurs at node w. We need to continue the same process to eliminate the double-red violation

at w , recursively.

A more detailed algorithm for inserting an element is described in Listing 43.1.

Listing 43.1 Inserting an Element to a Red-Black Tree

1 public boolean insert(E e) { 2 boolean successful = super .insert(e); 3 if (!successful) 4 return false ; // e is already in the tree 5 else { 6 ensureRBTree(e); 7 } 8 9 return true ; // e is inserted 10 } 11 12 /** Ensure that the tree is a red-black tree */ 13 private void ensureRBTree(E e) { 14 Get the path that leads to element e from the root.

Figure 43.11 Case 2 has four possible configurations.

30

25

40

u

v

w

50

x 30

35

40

u

v

w

50

x

(a) (b)

(c) (d)

30

45

40

u

v

w

50

x 30

55

40

u

v

w

50

x

Figure 43.12 Splitting a 4-node corresponds to recoloring the nodes in the red-black tree.

(a) A 4-node (b) Splitting a 4-node (c) Recoloring nodes

30

25

40

u

v

w

50

x

30 40 50

Insert a new element

40

v 50

x

Insert to its parent

25 30

43-8 Chapter 43 Red-Black Trees

15 int i = path.size() – 1 ; // Index to the current node in the path 16 Get u, v from the path. u is the node that contains e and v 17 is the parent of u. 18 Color u red; 19 20 if (u == root) // If e is inserted as the root, set root black 21 u.setBlack(); 22 else if (v.isRed()) 23 fixDoubleRed(u, v, path, i); // Fix double-red violation at u 24 } 25 26 /** Fix double-red violation at node u */ 27 private void fixDoubleRed(RBTreeNode u, RBTreeNode v, 28 ArrayList<TreeNode> path, int i) { 29 Get w from the path. w is the grandparent of u. 30 31 // Get v’s sibling named x 32 RBTreeNode x = (w.left == v)? 33 (RBTreeNode)(w.right) : (RBTreeNode)(w.left); 34 35 if (x == null || x.isBlack()) { 36 // Case 1: v's sibling x is black 37 if (w.left == v && v.left == u) { 38 // Case 1.1: u < v < w, Restructure and recolor nodes 39 } 40 else if (w.left == v && v.right == u) { 41 // Case 1.2: v < u < w, Restructure and recolor nodes 42 } 43 else if (w.right == v && v.right == u) { 44 // Case 1.3: w < v < u, Restructure and recolor nodes 45 } 46 else { 47 // Case 1.4: w < u < v, Restructure and recolor nodes 48 } 49 } 50 else { // Case 2: v's sibling x is red 51 Color w and u red 52 Color two children of w black. 53 54 if (w is root) { 55 Set w black; 56 } 57 else if (the parent of w is red) { 58 // Propagate along the path to fix new double-red violation 59 u = w; 60 v = parent of w; 61 fixDoubleRed(u, v, path, i – 2); // i – 2 propagates upward 62 } 63 } 64 }

The insert(E e) method (lines 1–10) invokes the insert method in the BST class to create

a new leaf node for the element (line 2). If the element is already in the tree, return false (line

4). Otherwise, invoke ensureRBTree(e) (line 6) to ensure that the tree satisfies the color and

black depth property of the red-black tree.

The ensureRBTree(E e) method (lines 13–24) obtains the path that leads to e from the

root (line 14), as shown in Figure 43.13. This path plays an important role to implement the

algorithm. From this path, you get nodes u and v (lines 16–17). If u is the root, color u black

(lines 20–21). If v is red, a double-red violation occurs at node u. Invoke fixDoubleRed to

fix the problem.

43-10 Chapter 43 Red-Black Trees

Figure 43.14 Inserting into a red-black tree: (a) initial empty tree; (b) inserting 34 ;

(c) inserting 3 ; (d) inserting 50 ; (e) inserting 20 causes a double red; (f) after recolor-

ing (Case 2); (g) inserting 15 causes a double red; (h) after restructuring and recoloring

(Case 1.4); (i) inserting 16 causes a double red; (j) after recoloring (Case 2); (k) insert-

ing 25 ; (l) inserting 27 causes a double red at 27 ; (m) a double red at 20 reappears after

recoloring (Case 2); and (n) after restructuring and recoloring (Case 1.2).

root in null^34 (a) (b) (c) (d) (e)

(g) (h)

(j) (k)

(m) (n)

3

34

3

34

50

3

34

50

20

15

34

50

(^320)

3

34

50

20

15

(f)

3

34

50

20

15

34

50

(^320)

16

15

34

50

(^320)

16 25

(l)

15

34

50

(^320)

16 25

27

15

34

50

(^320)

16 25

27

15

20

34

(^3 )

27

50

(i)

15

34

50

(^320)

16

43.5 Overriding the delete Method 43-

A double black in a red-black tree corresponds to an empty node for u (i.e., underflow

situation) in the corresponding 2-4 tree, as shown in Figure 43.16(b). To fix the double-black

problem, we will perform equivalent transfer and fusion operations. Consider three cases:

Case 1 : The sibling y of childOfu is black and has a red child. This case has four possible con-

figurations, as shown in Figures 43.17(a), 43.18(a), 43.19(a), and 43.20(a). The dashed circle

denotes that the node is either red or black. To eliminate the double-black problem, restructure

and recolor the nodes, as shown in Figures 43.17(b), 43.18(b), 43.19(b), and 43.20(b).

Figure 43.16 (a) childOfu is denoted double black. (b) u corresponds to an empty node

in a 2-4 tree.

(a)

u is black

parentOfu

childOfu is black or null

u

parentOfu

(b)

Figure 43.15 u is an external node and childOfu may be null.

(a) Before deleting u (b) After deleting u

u

parentOfu

childOfu

u

parentOfu

childOfu

Figure 43.17 Case 1.1: The sibling y of childOfu is black and y1 is red.

(a) (b)

parent

childOfu

y

y 1

y 2

parent childOfu is y double black

y 1 y 2

Figure 43.18 Case 1.2: The sibling y of childOfu is black and y2 is red.

parent childOfu is y doubleblack

y 1 y 2

parent

childOfu

y 2

y

y 1 y 2 .left y 2 .right

(a) (^) (b)

43.5 Overriding the delete Method 43-

Note Figures 43.22 and 43.23 show that childOfu is a right child of parent. If childOfu is a left child of parent , recoloring is performed identically.

Note Case 2 corresponds to a fusion operation in the 2-4 tree. For example, the corresponding 2-4 tree for Figure 43.22(a) is shown in Figure 43.24(a), and it is transformed into Figure 43.24(b) through a fusion operation.

Case 3: The sibling y of childOfu is red. In this case, perform an adjustment operation. If

y is a left child of parent , let y1 and y2 be the left and right children of y , as shown in

Figure 43.25. If y is a right children of parent , let y1 and y2 be the left and right child of

y , as shown in Figure 43.26. In both cases, color y black and parent red. childOfu is still

a fictitious double-black node. After the adjustment, the sibling of childOfu is now black,

and either Case 1 or Case 2 applies. If Case 1 applies, a one-time restructuring and recoloring

operation eliminates the double-black problem. If Case 2 applies, the double-black problem

cannot reappear, since parent is now red. Therefore, one-time application of Case 1 or Case 2

will complete Case 3.

Note Case 3 results from the fact that a 3-node may be transformed in two ways to a red-black tree, as shown in Figure 43.27.

Figure 43.23 Case 2: Recoloring propagates the double-black problem if parent is black.

parent parent

y (^) y

y (^1) y y (^2 1) y 2

childOfu

(a) (b)

childOfu is double black

Figure 43.24 Case 2 corresponds to a fusion operation in the corresponding 2-4 tree.

(a) (b)

u

parent

childOfu

y parent

childOfu

y

...

Figure 43.25 Case 3.1: y is a left red child of parent.

(a) (b)

parent

y

y 1 y 2

childOfu is double black (^) y parent 1

y 2

y

childOfu is double black

43-14 Chapter 43 Red-Black Trees

Based on the foregoing discussion, Listing 43.2 presents a more detailed algorithm for delet-

ing an element.

Listing 43.2 Deleting an Element from a Red-Black Tree 1 public boolean delete(E e) { 2 Locate the node to be deleted 3 if (the node is not found) 4 return false ; 5 6 if (the node is an internal node) { 7 Find the rightmost node in the subtree of the node; 8 Replace the element in the node with the one in rightmost; 9 The rightmost node is the node to be deleted now; 10 } 11 12 Obtain the path from the root to the node to be deleted; 13 14 // Delete the last node in the path and propagate if needed 15 deleteLastNodeInPath(path); 16

Figure 43.26 Case 3.2: y is a right red child of parent.

(a) (^) (b)

parent

y

childOfu is y 1 y 2 double black y 1

y 2

y

childOfu is double black

parent

Figure 43.27 A 3-node may be transformed in two ways to red-black tree nodes.

u

y parent

childOfu

y 1 y 2 or

parent

childOfu is double black

childOfu is double black

y

y 1 y 2

u

childOfu

(a)

(b)

(c)

y

y 1

y 2 u

childOfu

parent

43-16 Chapter 43 Red-Black Trees

77 fixDoubleBlack(grandparent, parent, db, path, i − 1 ); 78 } 79 } 80 else if (y.isRed()) { 81 if (parent.right == db) { 82 // Case 3.1: y is a left red child of parent 83 parent.left = y2; 84 y.right = parent; 85 } 86 else { 87 // Case 3.2: y is a right red child of parent 88 parent.right = y.left; 89 y.left = parent; 90 } 91 92 parent.setRed(); // Color parent red 93 y.setBlack(); // Color y black 94 connectNewParent(grandparent, parent, y); // y is new parent 95 fixDoubleBlack(y, parent, db, path, i − 1 ); 96 } 97 }

The delete(E e) method (lines 1–19) locates the node that contains e (line 2). If the node

does not exist, return false (lines 3–4). If the node is an internal node, find the right most

node in its left subtree and replace the element in the node with the element in the right most

node (lines 6–9). Now the node to be deleted is an external node. Obtain the path from the root

to the node (line 12). Invoke deleteLastNodeInPath(path) to delete the last node in the

path and ensure that the tree is still a red-black tree (line 15).

The deleteLastNodeInPath method (lines 22–36) obtains the last node u , parentOfu ,

grandparendOfu , and childOfu (lines 23–26). If childOfu is the root or u is red, the tree

is fine (lines 29–30). If childOfu is red, color it black (lines 31–32). We are done. Otherwise,

u is black and childOfu is null or black. Invoke fixDoubleBlack to eliminate the double-

black problem (line 35).

The fixDoubleBlack method (lines 39–97) eliminates the double-black problem. Obtain

y , y1 , and y2 (line 42). y is the sibling of the double-black node. y1 and y2 are the left and

right children of y. Consider three cases:

1. If y is black and one of its children is red, the double-black problem can be fixed by

one-time restructuring and recoloring in Case 1 (lines 44–63).

2. If y is black and its children are null or black, change y to red. If parent of y is black,

denote parent to be the new double-black node and invoke fixDoubleBlack recur-

sively (line 77).

3. If y is red, adjust the nodes to make parent a child of y (lines 84, 89) and color parent

red and y black (lines 92–93). Make y the new parent (line 94). Recursively invoke

fixDoubleBlack on the same double-black node with a different color for parent

(line 95).

Figure 43.28 shows the steps of deleting elements. To delete 50 from the tree in Figure 43.28(a),

apply Case 1.2, as shown in Figure 43.28(b). After restructuring and recoloring, the new tree

is as shown in Figure 43.28(c).

When deleting 20 in Figure 43.28(c), 20 is an internal node, and it is replaced by 16 , as

shown in Figure 43.28(d). Now Case 2 applies to deleting the rightmost node, as shown in

Figure 43.28(e). Recolor the nodes results in a new tree, as shown in Figure 43.28(f).

When deleting 15 , connect node 3 with node 20 and color node 3 black, as shown in

Figure 43.28(g). We are done.

43.5 Overriding the delete Method 43-

Figure 43.28 Delete elements from a red-black tree.

15

20

34

(^3 )

27

50

15

20

34

(^3 )

27

null

15

20

27

3 16 25 34

(a) Delete 50 (b) Case 1.2 (c) Delete 20

15

16

27

3 16 25 34

15

16

27

(^3) null 25 34

15

16

27

3 25 34

(d) Copy 16 to replace 20 (e) Case 2 (f) Delete 15

3

16

27

25 34

null

16

27

25 34

16

27

34

null 25

(g) Delete 3 (h) Case 3 (i) Case 2

16

27

34

25

16

27

34

27

null 34

(j) Delete 25 (k) Delete 16 (l) Case 2

27

34

27 root: null

(m) Delete 34 (n) Delete 27 (o) Empty tree

After deleting 25 , the new tree is as shown in Figure 43.28(j). Now delete 16. Apply Case

2, as shown in Figure 43.28(k). The new tree is shown in Figure 43.28(l).

After deleting 34 , the new tree is as shown in Figure 43.28(m).

After deleting 27 , the new tree is as shown in Figure 43.28(n).

43.6 Implementing RBTree Class 43-

41 // v is the parent of of u, if exists 42 RBTreeNode v = (u == root)? null : 43 (RBTreeNode)(path.get(i − 1 )); 44 45 u.setRed(); // It is OK to set u red 46 47 if (u == root) // If e is inserted as the root, set root black 48 u.setBlack(); 49 else if (v.isRed()) 50 fixDoubleRed(u, v, path, i); // Fix double-red violation at u 51 } 52 53 /** Fix double-red violation at node u */ 54 private void fixDoubleRed(RBTreeNode u, RBTreeNode v, 55 ArrayList<TreeNode> path, int i) { 56 // w is the grandparent of u 57 RBTreeNode w = (RBTreeNode)(path.get(i − 2 )); 58 RBTreeNode parentOfw = (w == root)? null : 59 (RBTreeNode)path.get(i – 3 ); 60 61 // Get v's sibling named x 62 RBTreeNode x = (w.left == v)? 63 (RBTreeNode)(w.right) : (RBTreeNode)(w.left); 64 65 if (x == null || x.isBlack()) { 66 // Case 1: v's sibling x is black 67 if (w.left == v && v.left == u) { 68 // Case 1.1: u < v < w, Restructure and recolor nodes 69 restructureRecolor(u, v, w, w, parentOfw); 70 71 w.left = v.right; // v.right is y3 in Figure 43. 72 v.right = w; 73 } 74 else if (w.left == v && v.right == u) { 75 // Case 1.2: v < u < w, Restructure and recolor nodes 76 restructureRecolor(v, u, w, w, parentOfw); 77 v.right = u.left; 78 w.left = u.right; 79 u.left = v; 80 u.right = w; 81 } 82 else if (w.right == v && v.right == u) { 83 // Case 1.3: w < v < u, Restructure and recolor nodes 84 restructureRecolor(w, v, u, w, parentOfw); 85 w.right = v.left; 86 v.left = w; 87 } 88 else { 89 // Case 1.4: w < u < v, Restructure and recolor nodes 90 restructureRecolor(w, u, v, w, parentOfw); 91 w.right = u.left; 92 v.left = u.right; 93 u.left = w; 94 u.right = v; 95 } 96 } 97 else { // Case 2: v's sibling x is red 98 // Recolor nodes 99 w.setRed(); 100 u.setRed();

43-20 Chapter 43 Red-Black Trees

101 ((RBTreeNode)(w.left)).setBlack(); 102 ((RBTreeNode)(w.right)).setBlack(); 103 104 if (w == root) { 105 w.setBlack(); 106 } 107 else if (((RBTreeNode)parentOfw).isRed()) { 108 // Propagate along the path to fix new double-red violation 109 u = w; 110 v = (RBTreeNode)parentOfw; 111 fixDoubleRed(u, v, path, i − 2 ); // i – 2 propagates upward 112 } 113 } 114 } 115 116 /** Connect b with parentOfw and recolor a, b, c for a < b < c / 117 private void restructureRecolor(RBTreeNode a, RBTreeNode b, 118 RBTreeNode c, RBTreeNode w, RBTreeNode parentOfw) { 119 if (parentOfw == null) 120 root = b; 121 else if (parentOfw.left == w) 122 parentOfw.left = b; 123 else 124 parentOfw.right = b; 125 126 b.setBlack(); // b becomes the root in the subtree 127 a.setRed(); // a becomes the left child of b 128 c.setRed(); // c becomes the right child of b 129 } 130 131 @Override /* Delete an element from the RBTree. 132 * Return true if the element is deleted successfully 133 * Return false if the element is not in the tree */ 134 public boolean delete(E e) { 135 // Locate the node to be deleted 136 TreeNode current = root; 137 while (current != null ) { 138 if (e.compareTo(current.element) < 0 ) { 139 current = current.left; 140 } 141 else if (e.compareTo(current.element) > 0 ) { 142 current = current.right; 143 } 144 else 145 break ; // Element is in the tree pointed by current 146 } 147 148 if (current == null ) 149 return false; // Element is not in the tree 150 151 java.util.ArrayList<TreeNode> path; 152 153 // current node is an internal node 154 if (current.left != null && current.right != null ) { 155 // Locate the rightmost node in the left subtree of current 156 TreeNode rightMost = current.left; 157 while (rightMost.right != null ) { 158 rightMost = rightMost.right; // Keep going to the right 159 } 160