CTDL2_CH04_CayDoDen

Đ i H c Sư Ph m Tp.

H Chí Minh

CẤU TRÚC DỮ LIỆU 2

Chương 04: CÂY ĐỎ ĐEN

Ôn tập cây nhị phân
• Xem lại các kiến thức liên quan đến cây nhị phân [tìm kiếm [cân bằng]]] • Độ cao của cây nhị phân tìm kiếm cân bằng N node là O(logN) • Cây nhị phân cân bằng có chi phí thấp nhất. • Các loại cây tìm kiếm cân bằng:
– AVL Tree – Red – Black Tree – AA Tree – Splay Tree
CTDL2 – HIENLTH HCMUP HIENLTH, 2

a. Khái niệm cây đỏ đen

-Là cây nhị phân tìm kiếm -Đưa thêm yếu tố màu (RED, BLACK) để làm cơ sở cho sự cân bằng.

CTDL2 – HIENLTH HCMUP HIENLTH,

3

Các tính chất
1. Mọi nút chỉ có thể là đỏ (RED) hoặc đen (BLACK) 2. Nút gốc mang màu đen. Mọi nút lá (NIL) mang màu đen. 3. Nếu 1 nút là đỏ thì con của nó phải là đen (nghĩa là không có 2 nút đỏ liên tiếp) 4. Tất cả các đường đi từ một nút đã cho tới các lá chứa một số như nhau các nút đen.

CTDL2 – HIENLTH HCMUP HIENLTH,

4

Ví dụ:

CTDL2 – HIENLTH HCMUP HIENLTH,

5

Cây đỏ đen
• Chiều cao đen (black height – hb(x)) là số node đen trên đường đi từ node x đến lá (không bao gồm x) • Từ quy tắc [4] Không thể tồn tại node cha và node con cùng đỏ. Khi cây đỏ đen vi phạm quy tắc này gọi là hiện tượng xung đột đỏ - đỏ.

CTDL2 – HIENLTH HCMUP HIENLTH,

6

Nhận xét
• Cây đỏ đen có N nút trong (internal node) có chiều cao tối đa là 2logn(N+1) • Chiều cao của cây (h) <= 2 * chiều cao đen (hb) • Các nút lá là NIL (nút ngoài – external node) luôn là node đen. • Mỗi cạnh đến 1 node đen được gọi là cạnh đen. • Thời gian tìm kiếm O(logN)
CTDL2 – HIENLTH HCMUP HIENLTH, 7

Cây đỏ đen
Cấu trúc lưu trữ: • Thông tin lưu trữ tại node (key) • Địa chỉ node gốc của cây con bên trái (*pLeft) • Địa chỉ node gốc của cây con bên phải (*pRight) • Địa chỉ node cha (*pParent) • Thuộc tính màu của node (color)
CTDL2 – HIENLTH HCMUP HIENLTH, 8

b. Biểu diễn cây đỏ - đen
struct Node { int Node* int Node* }; Key; //Dữ liệu pLeft, *pRight; color; //RED - BLACK pParent; //Trỏ đến nút cha

typedef Node* pNode; struct RBTree{ pNode root; };
CTDL2 – HIENLTH HCMUP HIENLTH, 9

c. Một số thao tác đơn giản (tự viết)
+ Tìm kiếm và duyệt cây (giống BST) + Thêm node mới + Xóa node

+ Khởi tạo void Init (RBTree &t); + Kiểm tra rỗng int isEmpty (RBTree t);
CTDL2 – HIENLTH HCMUP HIENLTH, 10

d. Xuất cây ra màn hình
void PrintTree (RBTree t) { if (isEmpty(t)) { cout<<“Cây rỗng”; return; } Print(t.root, 0): }
CTDL2 – HIENLTH HCMUP HIENLTH, 11

d. Xuất cây ra màn hình (tt)
void Print (pNode p, int level) { if (!p) { textcolor(BLACK); for (int i = 0 ; i < level; ++ i) { cout<<“ “; cout<<“NULL “<<endl; }
CTDL2 – HIENLTH HCMUP HIENLTH, 12

d. Xuất cây ra màn hình (tt)
Print(p->pRight, level + 1); for (i= 0; i < level;i++) cout<<“ “; if (p->color == RED) textcolor (RED); else textcolor (BLACK); cout<<p->Key; Print(p->pLeft , level +1) } }
CTDL2 – HIENLTH HCMUP HIENLTH, 13

e. Chèn một nút vào cây đỏ đen
Chèn một nút như trong cây tìm kiếm nhị phân bình thường và gán cho nó màu đỏ.

B1. Tìm vị trí thích hợp để chèn khoá K B2. Phát sinh 1 nút mới có khoá K, màu đỏ (RED) và gắn liên kết tại vị trí tìm được. B3. Hiệu chỉnh lại cây nếu có vi phạm tính chất (tô màu lại & quay)
CTDL2 – HIENLTH HCMUP HIENLTH, 14

Các tính chất có thể vi phạm khi thêm nút
• Mọi node là đỏ hoặc đen OK • Node gốc là đen Not OK nếu thêm node mới là node gốc • Các node lá (NIL) phải luôn đen OK • Nếu 1 node là đỏ, các node con của nó phải là đen Not OK nếu cha node thêm màu đỏ 2 node đỏ liên tiếp. • Mọi đường dẫn từ gốc đến lá chứa một số lượng node đen như nhau OK
CTDL2 – HIENLTH HCMUP HIENLTH, 15

void RBTree_Insertion(RBTree &root, int key) { x = getNode(key,RED, NIL); BSTree_Insert(root, x); Insertion_Fixup(root, x); }

CTDL2 – HIENLTH HCMUP HIENLTH,

16

Gọi:
• X: Con trỏ, trỏ đến nút vừa chèn vào • P: Con trỏ, nút cha của nút trỏ bởi x • U: Con trỏ, trỏ đến nút anh em của nút trỏ bởi p • G: Con trỏ, trỏ đến nút cha của nút trỏ bởi p
Cháu ngo i CTDL2 – HIENLTH HCMUP HIENLTH,

g

p

u

x

x

Cháu n i 17

Một số định nghĩa

U

U

X là một node cháu ngoại nếu nó nằm cùng bên node cha P và P cùng bên node cha G. Ngược lại, X gọi là node cháu nội .

U

U CTDL2 – HIENLTH HCMUP HIENLTH,

18

* Phép quay phải tại y

y

x

γ

α

β
CTDL2 – HIENLTH HCMUP HIENLTH, 19

Phép quay (như BST)

y

Quay phải

x

x

γ β

Quay trái

α

y

α

β
CTDL2 – HIENLTH HCMUP HIENLTH,

γ
20

Các trường hợp sau khi thêm:
• Nếu p đen • Nếu p đỏ: Dừng (1)

– Nếu u đỏ, đảo màu 3 nút p, u, g (2) – Nếu u đen: • Nếu x là cháu ngoại của g: Thực hiện 1 phép quay (3) • Nếu x là cháu nội của g: Thực hiện 2 phép quay (4)

CTDL2 – HIENLTH HCMUP HIENLTH,

21

Trường hợp 1
• P đen Bình thường (dừng)

CTDL2 – HIENLTH HCMUP HIENLTH,

22

Trường hợp 2
• P đỏ, U đỏ Đảo màu G, P, U

g

g

p

u

p

u

x

x CTDL2 – HIENLTH HCMUP HIENLTH, 23

G P X P
Case 2 – P, U is Red Just Recolor and move up
CTDL2 – HIENLTH HCMUP HIENLTH, 24

U G

X

U

Trường hợp 3
• P đỏ, U đen, x là cháu ngoại P; Đổi màu P, G Quay tại

CTDL2 – HIENLTH HCMUP HIENLTH,

25

G P X S X
Case 3 – Zig-Zig Single Rotate P around G Recolor P and G
CTDL2 – HIENLTH HCMUP HIENLTH,

U P G

S

U
26

Trường hợp 4
• P đỏ, U đen, x là cháu nội Quay tại P (trở thành cháu ngoại), sau đó Quay tại G; Đổi màu P, G

Tương t TH3

CTDL2 – HIENLTH HCMUP HIENLTH,

27

G P S X P
Case 4 – Zig-Zag Double Rotate X around P; X around G Recolor G and X

U X G

S U
28

CTDL2 – HIENLTH HCMUP HIENLTH,

Hàm quay trái (tương tự cho quay phải)
void LeftRotate(RBTree t, pNode x){ pNode y = x->pRight; x->pRight = y->pLeft; //Bên phải x là β if (p->pLeft !=NULL) p->pLeft ->pParent = x; //cha β là x p->pParent = x->pParent; // cha của x là cha của y //nếu x là nút gốc if (x->pParent == NULL) t.root = y; //gốc mới sẽ là y else
CTDL2 – HIENLTH HCMUP HIENLTH, 29

Hàm quay trái (tt)
//trường hợp else => x không phải là gốc //Nếu x là con trái của cha nó if (x == (x->pParent)->pLeft) x->pParent->pLeft = y else x->pParent->pRight = y; y->pLeft = x; x ->pParent = y; }
CTDL2 – HIENLTH HCMUP HIENLTH, 30

Ví dụ: Chèn một nút vào cây đỏ đen
Lần lượt chèn vào các nút có giá trị: 50, 75, 25, 80, 100, 110, 105
50

“ông” x
75

“bác” x
25

“cha” x x
80

CTDL2 – HIENLTH HCMUP HIENLTH,

31

TH2: Cha, bác x đều có màu đỏ
- Cho cha và bác thành màu đen -Ông của x thành màu đỏ
(lưu ý: nút gốc qui ước là màu đen)
50

“ông” x
75

“bác” x
25

“cha” x x
80

CTDL2 – HIENLTH HCMUP HIENLTH,

32

TH3: Bác x đều có màu đen x là con phải của cha x
Quay trái tại ông của x đồng thời đổi màu cha của x và ông của x
50 50 75 25 80
100 100

80 25

x

x

75

CTDL2 – HIENLTH HCMUP HIENLTH,

33

50

80

25
100

75
110

105

x
CTDL2 – HIENLTH HCMUP HIENLTH, 34

TH4: x là con trái, cha x là phải hoặc x là con phải, cha x là trái Quay trái (phải) tại cha (không đổi màu)
50

80

25
100

75
105

TH.3

110

CTDL2 – HIENLTH HCMUP HIENLTH,

35

CODE
void Insert(RBTree &t, int k) { -Tìm vị trí cần chèn k -Phát sinh 1 nút x có khoá là k, màu đỏ, và chèn vào vị trí cần chèn //Bắt đầu cân bằng while (x!=t.root && x->pParent->color==RED) { //cha x là con trá của ông x if ( x -> p == x->pParent->pParent->pLeft) { //y là “bác” của x y = x->pParent->pParent->pRight; }
CTDL2 – HIENLTH HCMUP HIENLTH, 36

CODE
if (y->color == RED){ //TH1 x->pParent->Color = BLACK; y->color = BLACK; x->pParent -> pParent -> color = RED x = x->pParent -> pParent; }

CTDL2 – HIENLTH HCMUP HIENLTH,

37

CODE
else if (x== x->pParent->pRight){ //TH3 x = x->pParent; LeftRotate(t,x); } //TH2 luôn xảy ra sau đó X->pParent ->color = BLACK; X->pParent->pParent->color = RED; RightRotae(t,x->pParent->pParent); }
CTDL2 – HIENLTH HCMUP HIENLTH, 38

CODE

else //TH: cha của x là con phải của “ông”x { //Làm tương tự như trên,đổi pRight<->pLeft } t.root -> color = BLACK;

CTDL2 – HIENLTH HCMUP HIENLTH,

39

Red-Black Trees
Insertion example 11 2 14

1

7

15

5

8

4

Violation of rule( after 4 added to the tree)

CTDL2 – HIENLTH HCMUP HIENLTH,

40

Red-Black Trees
Insertion example 11 2 14

1

7

15

5

8

4

Case 1

CTDL2 – HIENLTH HCMUP HIENLTH,

41

Red-Black Trees
Insertion example 11 7 14

2 1 5

8

15

4

Case 2

CTDL2 – HIENLTH HCMUP HIENLTH,

42

Red-Black Trees
Insertion example 7

2 1 5 8

11 14

4

15

Case 3

CTDL2 – HIENLTH HCMUP HIENLTH,

43

CTDL2 – HIENLTH HCMUP HIENLTH,

44

CTDL2 – HIENLTH HCMUP HIENLTH,

45

f. Huỷ một nút trong cây đỏ đen
• Tìm và hủy giống cây NPTK (BST). • Kiểm tra tính cân bằng mất cân bằng cân bằng lại. Sau khi xóa: • Nếu y đỏ Không cần cân bằng lại. • Nếu y đen:
– Tất cả các đường đi con từ gốc đến nút lá (qua y) sẽ ít hơn 1 nút đen so với những đường đi còn lại (vi phạm t/c 4) – Nếu p và x cùng đỏ thì vi phạm t/c 3.
CTDL2 – HIENLTH HCMUP HIENLTH, 46

Gọi:
• y: Con trỏ, trỏ đến nút bị xóa thật sự • x: Con trỏ, trỏ đến nút con của nút trỏ bởi y, sẽ thay thế nút y • w: Con trỏ, trỏ đến nút anh em của nút trỏ bởi x • p: Con trỏ, trỏ đến nút cha của nút trỏ bởi y

p

y

w

x

CTDL2 – HIENLTH HCMUP HIENLTH,

47

Dấu hiệu đen (black token)
• Được gán cho nút trỏ bởi x (nút con thật sự của nút bị xóa y) • Báo hiệu con đường đi qua các nút có chứa nó sẽ ít hơn những con đường khác 1 nút đen • “dấu hiệu đen” đi ngược lên cây cho tới khi chiều cao cây được đảm bảo. • Nút chứa dấu hiệu đen, bản thân là:
– Nút đen – Nút đỏ nút đen kép nút đỏ đen

• Là khái niệm trừu tượng, không cài đặt
CTDL2 – HIENLTH HCMUP HIENLTH, 48

Quy ước
Do khi xoá và cân bằng cây, sẽ có nhiều trường hợp cần phải xử lý, trong đó có việc kiểm tra nút là nút NULL? Giải pháp : thay tất cả các nút NULL bằng 1 nút đặc biệt, có tên là Null. Đây là nút thật sự luôn có màu đen, các trị của nó (key, trái, phải, cha) được gán bất kỳ

CTDL2 – HIENLTH HCMUP HIENLTH,

49

Quy ước
pNode Null; void main() { Null -> color = BLACK; Null ->pParent= Null->pLeft=Null->pRight = NULL; Null -> Key = 0; }

CTDL2 – HIENLTH HCMUP HIENLTH,

50

Phân tích

Khi nào cần cân bằng lại cây? + Khi nút bị xoá là nút có màu đen Khi cân bằng cần để ý đến sự vi phạm t/c nào? + t/c chiều cao cây đen

CTDL2 – HIENLTH HCMUP HIENLTH,

51

Phân tích
Khi huỷ một nút đen thì chiều cao đen của nhánh chứa nó sẽ bị sụt giảm 1 đơn vị, ta có thể: + Biến nút đen cùng cấp ở cây con còn lại thành nút đỏ (nếu được) + Thực hiện xoay cây để tạo sự cân bằng => KL: Kết hợp đổi màu và xoay cây

CTDL2 – HIENLTH HCMUP HIENLTH,

52

CODE
void Delete(RBTree &t, int k) { //Tìm nút z cần xoá if (isEmpty(t)) return; pNode z = t.root; while (z!=Null && z->key !=k){ if (z->key > k) z= z->pLeft; else z= z->pRight; } if (z==Null) return ; //Không tìm thấy
CTDL2 – HIENLTH HCMUP HIENLTH, 53

CODE
Xác định nút y là nút cần thực sự xoá If (z->pLeft ==Null !! z->pRight == Null) y = z; //z không đủ 2 con => xoá else //y chỉ có thể có 1 con y = SearchStandFor(z);

CTDL2 – HIENLTH HCMUP HIENLTH,

54

CODE
//Tiến hành xoá y pNode x; // x là nút con của y if (y->pLeft != Null) x=y->pLeft; else x = y->pRight; //cha của x là cha của y //Nếu x là Null vẫn không báo lỗi x->pParent = y->pParent;
CTDL2 – HIENLTH HCMUP HIENLTH, 55

CODE
if (y->pParent == Null) //y là gốc t.root = x; else if (y->Parent->pLeft ==y) y->pParent->pLeft = x; else y->pParent->pRight =x;

CTDL2 – HIENLTH HCMUP HIENLTH,

56

CODE
//Kiểm tra cân bằng if (y != z) // y là phần tử thế mạng z->key = y->key; if (y->color == BLACK) FIXUP(t,x); // cân bằng lại //Xoá y y->pLeft = y->pRight = y->pParent=Null; Delete y;
CTDL2 – HIENLTH HCMUP HIENLTH, 57

Cân bằng lại cây sau khi xoá một nút đen
x: con trỏ, trỏ tới nút đang thiếu đen w: con trỏ, trỏ tới nút anh/em của x p: con trỏ, trỏ tới nút cha của x

CTDL2 – HIENLTH HCMUP HIENLTH,

58

TH1: x đỏ hoặc gốc
• Nút x chứa “dấu hiệu đen” là nút đỏ (nút đỏ - đen) hay nút gốc. Xử lý: • Tô màu nút đỏ đen sang màu đen. • Loại bỏ dấu hiệu đen và kết thúc

CTDL2 – HIENLTH HCMUP HIENLTH,

59

TH2: x đen kép, w và 2 con w đều đen
• Đổi màu nút anh em w sang đỏ • Đổi màu P đen (bất kể P trước đó màu đỏ hay màu đen) • Di chuyển “dấu hiệu đen” lên trên 1 cấp (theo hướng gốc của cây)

CTDL2 – HIENLTH HCMUP HIENLTH,

60

TH2: x đen kép, w và 2 con w đều đen
x
A B w Đổi màu w sang đỏ D C E B A D

α β

α

β
δ
x
A B

δ

γ

ε η

C

E

γ

ε η
w Đổi màu w sang đỏ D A B D

α β

C

E

α

β

δ γ

ε η

C

δ γ

ε η
61

E

CTDL2 – HIENLTH HCMUP HIENLTH,

TH3: x đen kép, w đỏ, 2 con w đen, p đen
• Đảo màu nút p và w • Thực hiện phép quay tại w (theo hướng đưa w lên, p xuống w làm ông của x) • Dấu hiệu đen vẫn chỉ vào nút x ban đầu
p x w w

p x

Trở về một trong các trường hợp trên.

CTDL2 – HIENLTH HCMUP HIENLTH,

62

TH3: w đỏ

D B

x
A

w
D

Left Rotate Đổi màu
B E

α β

x
C E

ε η
w C mới

A

δ γ

ε η

α

β

δ γ
63

CTDL2 – HIENLTH HCMUP HIENLTH,

TH4: x đen kép, w đen, 1 trong 2 con w đỏ
Gọi z là nút con của w có màu đỏ. (w có ít nhất một con đỏ gọi là z) Có 2 trường hợp xảy ra: • 4a) z là cháu nội • 4b) z là cháu ngoại Xử lý: • 4a) chuyển sang 4b) nhờ phép quay và đổi màu • 4b) được xử lý bằng phép quay và đổi màu
CTDL2 – HIENLTH HCMUP HIENLTH, 64

TH4a: w đen con trái w màu đỏ
Đỏ/đen B B B

Quay phải tại W

w mới
A C

x
A

α β

w z
C

D

Đổi màu
E

x
α

β

δ γ

D

z mới

δ γ

ε η
CTDL2 – HIENLTH HCMUP HIENLTH,

E

ε η
65

Xử lý
• 4a) chuyển sang 4b):
– Đổi màu Z và W – Quay tại Z (theo hướng đưa z lên, w xuống)

• Xử lý 4b)
– Quay tại W (theo hướng đưa W lên, P xuống) – Đảo màu P, W – Z đổi theo màu P – Mất dấu hiệu đen

CTDL2 – HIENLTH HCMUP HIENLTH,

66

TH4b: w đen con phải w màu đỏ
Đỏ/đen

p x
A

D B

Quay trái tại cha của x

w
C

D

Đổi màu
E

B

E

α β

z
α

ε
A C

η

δ γ

ε η

β δ

γ
67

CTDL2 – HIENLTH HCMUP HIENLTH,

Bài tập áp dụng
Cho cây đỏ đen như sau:
50

25 10 30 55

60

65

Lần lượt xóa các nút sau: 55, 50.

CTDL2 – HIENLTH HCMUP HIENLTH,

68

Cây 2-3-4
+ Cây 2-3-4 là cây nhiều nhánh mà mỗi node của nó có thể có đến bốn node con và ba mục dữ liệu.

CTDL2 – HIENLTH HCMUP HIENLTH,

69

Cây 2-3-4
Node không phải là lá: • Một node với một mục dữ liệu thì luôn luôn có 2 con. • Một node với hai mục dữ liệu thì luôn luôn có 3 con. • Một node với ba mục dữ liệu thì luôn luôn có 4 con. Đối với mọi node với số con là k và số mục dữ liệu là d, thì : k = d + 1
CTDL2 – HIENLTH HCMUP HIENLTH, 70

Các loại nút

2 – node
Một mục dữ liệu 2 node con.

3 – node
Hai mục dữ liệu 3 node con.

4 – node
Ba mục dữ liệu 4 node con.

CTDL2 – HIENLTH HCMUP HIENLTH,

71

Các trường hợp của cây 2-3-4

CTDL2 – HIENLTH HCMUP HIENLTH,

72

Các trường hợp của cây 2-3-4

2 - 3 - 4 tree
CTDL2 – HIENLTH HCMUP HIENLTH, 73

Các trường hợp của cây 2-3-4

CTDL2 – HIENLTH HCMUP HIENLTH,

74

Cấu trúc một nút

struct Node { char key[3]; int type; // 2 , 3, 4 – Node Node* next[4]; };

CTDL2 – HIENLTH HCMUP HIENLTH,

75

Tổ chức cây 2-3-4
• Trong cây 2-3-4, các nút lá đều nằm trên cùng một mức. Các node ở mức trên thường không đầy đủ, nghĩa là chúng có thể chứa chỉ 1 hoặc 2 mục dữ liệu thay vì 3 mục. • Lưu ý rằng cây 2-3-4 là cây cân bằng. Nó vẫn giữ được sự cân bằng khi thêm vào các phần tử có thứ tự (tăng dần hoặc giảm dần).

CTDL2 – HIENLTH HCMUP HIENLTH,

76

Cách chèn nút
+ Bottom – up: Mở rộng cây về phía gốc, tách từ dưới lên, tràn node => tách + Top – Down: đi từ trên xuống, gặp nút đầy thì tách, rồi tìm vị trí thích hợp để chèn

Ví dụ: (xem demo trên web)

CTDL2 – HIENLTH HCMUP HIENLTH,

77

Thêm nút
• Theo nguyên lý Top – Down (đi từ trên xuống), gặp nút đầy thì tách rồi mới chèn. • Dữ liệu thêm luôn được chèn vào node lá. • Nếu node thêm vào chưa đầy thêm vào bình thường. • Node đầy dữ liệu (có 3 mục dữ liệu) thì tách. Ta có 2 trường hợp:
– Tách node gốc – Tách node không phải là gốc
CTDL2 – HIENLTH HCMUP HIENLTH, 78

Tách nút gốc
• Node gốc đầy tách trước, chèn sau • Giả sử node gốc có 3 mục dữ liệu A, B, C (đã được sắp thứ tự). Quá trình tách:
– Node mới được tạo ra để trở thành gốc mới và là cha của node được tách. – Node mới thứ hai được tạo ra để trở thành anh em với node được tách. – Mục dữ liệu C được dịch đưa sang node anh em mới. – Mục dữ liệu B được dịch đưa sang node gốc mới. – Mục dữ liệu A vẫn không đổi. – Hai node con bên phải nhất của node được phân chia bị hủy kết nối khỏi nó và kết nối đến node mới bên phải.
CTDL2 – HIENLTH HCMUP HIENLTH, 79

Ví dụ về tách node gốc

CTDL2 – HIENLTH HCMUP HIENLTH,

80

Ví dụ Tách nút

CTDL2 – HIENLTH HCMUP HIENLTH,

81

Ví dụ Tách nút

CTDL2 – HIENLTH HCMUP HIENLTH,

82

Ví dụ về chèn nút

CTDL2 – HIENLTH HCMUP HIENLTH,

83

Ví dụ về xóa node
• Khóa k nằm trong nút lá u và u có nhiều hơn một khóa: giải phóng khóa k khỏi u .

CTDL2 – HIENLTH HCMUP HIENLTH,

84

Ví dụ về xóa node
• Khóa k nằm trong nút lá u và u chỉ có một khóa và tồn tại nút anh em v của u có nhiều hơn một khóa thì bằng phép dịch chuyển dần có thể dịch chuyển một khóa của v đến u khiến u trở thành 3-nút và quay về trường hợp 1.

CTDL2 – HIENLTH HCMUP HIENLTH,

85

Ví dụ về xóa node
• Khóa k nằm trong nút lá u và u chỉ có một khóa và tất cả các nút anh em của u chỉ có một khóa thì bằng phép gộp u với nút anh em kề nó sẽ khiến u trở thành 3-nút và quay về trường hợp 1.

CTDL2 – HIENLTH HCMUP HIENLTH,

86

Ví dụ về xóa node
• Khóa k nằm trong nút trong u: Khi đó tìm khóa tiền nhiệm hoặc khóa kế vị của k (khóa này luôn nằm trong nút lá). Thay k bởi khóa đó, và giải phóng khóa đó tkhỏi nút chứa nó (quay về trường hợp 1). Tuy việc dùng khóa tiền nhiệm hay kế vị đều được, nhưng nên chọn khóa nào trong chúng nằm trong nút có hai khóa trở lên, nếu cả hai đều nằm trong các 2-nút thì chọn khóa nào cũng được.

CTDL2 – HIENLTH HCMUP HIENLTH,

87

Đánh giá

+ Cây cân bằng + Chi phí tìm kiếm là O(log(n))

CTDL2 – HIENLTH HCMUP HIENLTH,

88

Biến đổi cây 2-3-4 sang cây đỏ đen
• Biến đổi bất kỳ 2-node ở cây 2-3-4 sang node đen ở cây đỏ-đen.

CTDL2 – HIENLTH HCMUP HIENLTH,

89

Biến đổi cây 2-3-4 sang cây đỏ đen
• Biến đổi bất kỳ 3-node sang node con C (với hai con của chính nó) và node cha P (với các node con C và node con khác). C được tô màu đỏ và P được tô màu đen

Node cha: đen Node con: đ

CTDL2 – HIENLTH HCMUP HIENLTH,

90

Biến đổi cây 2-3-4 sang cây đỏ đen
• Biến đổi bất kỳ 4-node sang node cha P và cả hai node con C1, C2 màu đỏ.

Node cha: đen Node con: đ

CTDL2 – HIENLTH HCMUP HIENLTH,

91

Câu hỏi và thảo luận

CTDL2 – HIENLTH HCMUP HIENLTH,

92

Sign up to vote on this title
UsefulNot useful