Một đồ thị liên thông và không có chu trình đơn được gọi là cây (Tree). Cây không chứa khuyên và cạnh song song. Cây đã được dùng từ năm 1857, khi nhà toán học Anh tên là Authur Cayley dùng cây để xác định những dạng khác nhau của hợp chất hoá học. Từ đó cây đã được dùng để giải quyết nhiều bài toán trong lĩnh vực khác nhau. Cây rất hay được sử dụng trong tin học.
BỘ GIÁO DỤC VÀ ĐÀO TẠO TRƯỜNG ĐẠI HỌC SƯ PHẠM TP HỒ CHÍ MINH KHOA CƠNG NGHỆ THƠNG TIN CAO HỌC NGÀNH: KHOA HỌC MÁY TÍNH 🙟🕮🙝 BÁO CÁO NHÓM ĐỀ TÀI: TREES Giảng viên hướng dẫn : HUỲNH VĂN ĐỨC Sinh viên thực : ĐINH THUÝ CHIỀU NGUYỄN THANH THUỶ THIỀU THỊ NGỌC TRIỆU Lớp : KHMT – K28 TP Hồ Chí Minh, tháng năm 2018 MỤC LỤC GIỚI THIỆU 1.1 1.2 1.3 1.4 1.5 Lịch sử Định nghĩa: Mệnh đề Định lý Tính chất 5 5 BINARY SEARCH TREES 2.1 2.2 2.3 2.4 2.5 2.6 2.7 Tổng quát Duyệt Tìm kiếm phần tử BST Thêm node vào BST Xoá node khỏi BST Đánh giá Áp dụng BST vào quản lý sinh viên 2.7.1 2.7.2 Khai báo cấu trúc liệu quản lý sinh viên Thao tác với sinh viên CÂY NHỊ PHÂN CÂN BẰNG (AVL Tree) 3.1 3.2 3.3 3.4 3.5 3.6 Giới thiệu Lịch sử cân (AVL Tree) Định nghĩa Chiều cao AVL Cấu trúc liệu cho AVL Các thao tác đặc trưng AVL 3.6.1 3.6.2 Các trường hợp cân Tái cân 3.6.2.1 3.6.2.2 3.6.2.3 3.6.2.4 3.6.3 3.6.4 3.6.5 3.7 10 12 12 12 13 14 14 14 14 15 15 16 16 17 Left of left Right of right Right of left Left of right 17 18 18 19 Cân lại AVL Thêm phần tử AVL Huỷ phần tử AVL Áp dụng 20 20 21 23 3.7.1 3.7.2 Phân tích Chương trình tham khảo 23 23 Red-Black Trees 4.1 4.2 4.3 4.4 27 Giới thiệu Thêm node Xoá node Áp dụng 27 28 30 35 Tài liệu tham khảo: Phân công thực hiện: 36 37 DANH MỤC HÌNH ẢNH Hình Cây nhị phân tìm kiếm Hình 2 Duyệt theo thứ tự NLR Hình Duyệt theo thứ tự LNR Hình Duyệt theo thứ tự LRN Hình Tìm kiếm node BST Hình 2.6 Thêm node vào BST Hình 2.7 Xóa node Hình 2.8 Xóa node có Hình Xóa node có đủ hai 8 10 10 11 11 Hình Cây cân AVL Hình Ví dụ chiều cao cân Hình 3 Cây cân (1) Hình Cây cân (2) Hình Quay đơn Left of Left Hình Quay đơn Right of Right Hình Quay kép Right of Left (1) Hình Quay kép Right of Left (2) Hình Quay kép Left of Right 14 15 16 16 17 17 18 18 19 Hình Ví dụ đỏ - đen (1) Hình Ví dụ đỏ - đen (2) Hình Thêm node trường hợp Hình 4 Thêm node trường hợp Hình Thêm node trường hợp Hình Xóa node trường hợp Hình Xóa node trường hợp Hình Xóa node trường hợp Hình Xóa node trường hợp 27 28 30 30 31 33 33 34 35 GIỚI THIỆU 1.1 Lịch sử Một đồ thị liên thơng khơng có chu trình đơn gọi (Tree) Cây không chứa khuyên cạnh song song Cây dùng từ năm 1857, nhà toán học Anh tên Authur Cayley dùng để xác định dạng khác hợp chất hố học Từ dùng để giải nhiều toán lĩnh vực khác Cây hay sử dụng tin học Chẳng hạn, người ta dùng để xây dựng thuật tốn có hiệu để định vị phần tử danh sách Cây dùng để xây dựng mạng máy tính với chi phí rẻ cho đường điện thoại nối máy phân tán Cây dùng để tạo mã có hiệu để lưu trữ truyền liệu Dùng mơ hình thủ tục mà để thi hành cần dùng dãy định 1.2 Định nghĩa: Cây thường định nghĩa đồ thị vô hướng, liên thông không chứa chu trình có hai đỉnh, cặp đỉnh ln tồn đường đơn Cây hay sử dụng tin học Trong khoa học máy tính cấu trúc liệu khơng tuyến tính Cấu trúc dùng để xây dựng thuật toán có hiệu để định vị phần tử danh sách, ứng dụng giải thuật tìm kiếm, giải thuật xếp nhiều toán khác Cây dùng để xây dựng mạng máy tính với chi phí rẻ cho đường điện thoại nối phân tán, tạo mã co hiệu để lưu trữ truyền liệu Cây dùng để biểu diễn toán định (cây định), biểu diễn q trình tính tốn biểu thức đại số Vì đặc biệt có giá trị nghiên cứu toán xếp Các đặc biệt: (1) Cây nhị phân (2) Cây nhị phân tìm kiếm (Binary Search Trees - BST) (3) Cây AVL (4) Cây đỏ đen (5) Cây 2-3-4 (6) B-Cây (7) Đống (heap) (8) Cây biểu diễn tập hợp 1.3 Mệnh đề Nếu T có n đỉnh T có hai đỉnh treo 1.4 Định lý Cho T đồ thị có n >= đỉnh Các điều sau tương đương: - T - T liên thơng có n-1 cạnh - T khơng chứa chu trình có n-1 cạnh - T liên thông cạnh cầu - hai đỉnh phân biệt T ln có đường sơ cấp - T không chứa chu trình thêm cạnh có chu trình 1.5 Tính chất Chúng ta thường cần kết liên quan tới số đỉnh số cạnh loại Định lý 1: Một đồ thị vô hướng cặp đỉnh ln tồn đường đơn Định lý 2: Cây với n đỉnh có n - cạnh Định lý 3: Cây m - phân đầy đủ với i đỉnh có tất n = m.i + đỉnh BINARY SEARCH TREES 2.1 Tổng quát Cây nhị phân tìm kiếm (CNPTK) nhị phân nút, khóa nút xét lớn khóa tất nút thuộc trái nhỏ khóa tất nút thuộc phải Cài đặt nhị phân tìm kiếm sử dụng danh sách liên kết: struct node { int data; node *left, *right; }; typedef node * Pnode Dưới ví dụ nhị phân tìm kiếm: Hình Cây nhị phân tìm kiếm Nhờ ràng buộc khóa CNPTK, việc tìm kiếm trở nên có định hướng Hơn nữa, cấu trúc việc tìm kiếm trở nên nhanh đáng kể Chi phí tìm kiếm trung bình khoảng log2N Cây nhị phần tìm kiếm cấu trúc liệu sử dụng để xây dựng cấu trúc liệu trừu tượng tập hợp, đa tập hợp, dãy kết hợp Nếu BST có chứa giá trị giống biểu diễn đa tập hợp Cây loại sử dụng bất đẳng thức không nghiêm ngặt Mọi nút trái có khóa nhỏ khóa nút cha, nút phải có nút lớn khóa nút cha Nếu BST khơng chứa giá trị giống biểu diễn tập hợp đơn trị lý thuyết tập hợp Cây loại sử dụng bất đẳng thức nghiêm ngặt Mọi nút trái có khóa nhỏ khóa nút cha, nút phải có nút lớn khóa nút cha Giá trị nhỏ nằm bên trái nhất, giá trị lớn nằm bên phải 2.2 Duyệt + Duyệt theo thứ tự trước (NLR): Kiểu duyệt trước tiên thăm nút gốc, sau thăm nút trái đến phải Thủ tục trình bày đơn giản sau: void NLR(BinaryNode a) { if(a!=NULL) { xử lý a; NLR(a ->left); NLR(a ->right); } } Ví dụ: Hình 2 Duyệt theo thứ tự NLR Thứ tự duyệt là: A B D E H I C F G + Duyệt theo thứ tự LNR Kiểu duyệt trước tiên thăm nút trái, sau thăm nút gốc đến phải void LNR(BinaryNode a) { if(a!=NULL) { LNR(a ->left); xử lý a; LNR(a ->right); } } Ví dụ: Hình Duyệt theo thứ tự LNR Thứ tự duyệt là: D B H E I A F C G + Duyệt theo thứ tự sau LRN Kiểu duyệt trước tiên thăm nút trái sau thăm đến phải cuối thăm nút gốc void LRN(BinaryNode a) { if(a!=NULL) { LRN(a ->left); LRN(a ->right); xử lý a; } } Ví dụ: Hình Duyệt theo thứ tự LRN Thứ tự duyệt là: D H I E B F G C A 2.3 Tìm kiếm phần tử BST Để thực tìm phần tử nhỏ ta bắt đầu tử nút gốc (root) thực duyệt bên trái có nút bên trái nhỏ gốc Điểm dừng phần tử nhỏ Tương tự, để tìm phần tử lớn ta gốc duyệt bên phải, điểm dừng phần tử lớn Để tìm phần tử có giá trị x NPTK, so sánh giá trị node gốc với x: Nếu node gốc = NULL khơng có x Ngược lại, x giá trị node gốc dừng, tìm node chứa x Nếu x > giá trị node gốc tìm x bên phải Nếu x < giá trị node gốc tìm x bên trái Thuật toán: Pnode search (Pnode tree,int x) { if(tree==NULL) return NULL; if(tree ->data==x) return tree; if(x < tree ->data) search(tree->left,x); else search(tree->right,x); } Ví dụ: Tìm node có giá trị 32 hình bên dưới: ✔ So sánh 32 với node gốc 20 , 32 >20 tìm tiếp bên phải có node gốc 35 ✔ So sánh 32 với node gốc 35 , 32 pLeft; P->pLett = Q->pRight; Q->pRight = P; P = Q; } void LeftBalance(AVLNODE* &P) { switch(P->pLeft->bal){ case 1: //mất cân trái trái RightRotate(P); P->bal = 0; P->pRight->bal = 0; break; case 2: LeftRotate(P->pLeft); RightRotate(P); switch(P->bal){ case 0: P->pLeft->bal= 0; P->pRight->bal= 0; break; case 1: P->pLeft->bal= 0; P->pRight->bal= 2; break; case 2: P->pLeft->bal= 1; P->pRight->bal= 0; break; } P->bal = 0; break; } } void RightBalance(AVLNODE* &P) { switch(P->pRight->bal){ case 1: RightRotate(P->pRight); LeftRotate(P); switch(P->bal){ case 0: 26 P->pLeft->bal= 0; P->pRight->bal= 0; break; case 1: P->pLeft->bal= 1; P->pRight->bal= 0; break; case 2: P->pLeft->bal= 0; P->pRight->bal= 2; break; } P → bal = 0; break; case 2: LeftRotate(P); P->bal = 0; P->pLeft->bal = 0; break; } } int InsertNode(AVLNODE* &tree, int x) { int res; if(tree==NULL){ tree = CreateNode(x); if(tree==NULL){ return -1; } return } else { if(tree->Key==x){ return 0; } else if(tree->Key > x){ res = InsertNode(tree->pLeft,x); if(res < 2) { return res; } switch(tree->bal){ case 0: tree->bal = 1; return 2; case 1: LeftBalance(tree); return 1; case 2: tree->bal = 0; return 1; 27 } } else{ res = InsertNode(tree->pRight,x); if(resbal){ case 0: tree->bal=2; return 2; case 1: tree->bal = 0; return 1; case 2: RightBalance(tree); return 1; } } } } void Traverse(AVLNODE* t) { if(t!=NULL) { Traverse(t->pLeft); printf("Khoa: %d, can bang: %d\n", t->Key,t->bal); Traverse(t->pRight); } } void RemoveAll(AVLNODE* &t) { if(t!=NULL){ RemoveAll(t->pLeft); RemoveAll(t->pRight); delete t; } } int _tmain(int argc, _TCHAR* argv[]) { AVLNODE *tree; tree = NULL; int Data; { printf("Nhap vao du lieu, -1 de ket thuc: "); scanf("%d", &Data); if (Data == -1) 28 break; InsertNode(tree, Data); }while (Data != -1); printf("\nCay AVL vua tao: \n"); Traverse(tree); RemoveAll(tree); return 0; } Red-Black Trees Hình Ví dụ đỏ đen (1) 4.1 Giới thiệu Cây đỏ đen (Red-Black Tree) tìm kiếm nhị phân tự cân bằng, Rudolf Bayer đưa vào năm 1972 với tên gọi "B-Tree cân bằng" tên đưa từ 1978 Leo J Guibas Robert Sedgewick Red-Black Tree cấu trúc phức tạp cho kết tốt thời gian trường hợp xấu Các phép tốn Red-Black Tree tìm kiếm (search), chèn (insert), xóa (delete) thời gian O (log n), n số phần tử Mỗi node Red-Black Tree có thêm bit để lưu trữ màu sắc (red black) Các bit màu sắc dùng để đảm bảo trì độ cân tương đối trình insert delete Một Red-Black Tree phải thỏa điều kiện sau: ● Tất node có màu sắc: red black ● Root luôn black ● Nếu node red, trực tiếp node black ● Tất đường (path) từ node đến (leaf) có số lượng black node Người ta chứng minh thỏa điều kiện có độ cân tương đối, độ cao n node ln nhỏ 2log(n+1) Các tìm kiếm nhị phân, bao gồm đỏ-đen, thỏa mãn tính chất: nút gán giá trị cho giá trị nút nhỏ tất giá trị nút thuộc phải lớn giá trị nằm trái Điều làm cho q trình tìm kiếm nhanh 29 Hình Ví dụ đỏ - đen (2) Có thể áp dụng phép chèn, xóa tìm kiếm nhị phân vào đỏ đen mà khơng cần sửa chữa đỏ đen trường hợp riêng tìm kiếm nhị phân Tuy nhiên, có số tính chất định nghĩa đỏ đen bị vi phạm Việc khơi phục tính chất đỏ đen cần số nhỏ cỡ O(log n) trung bình O(1) phép đổi màu (tốn thời gian) khơng q ba phép quay cho phép xóa, hai cho phép chèn Toàn giải thuật chèn xóa có độ phức tạp thời gian cỡ O(log n) Chú ý: Nhãn N dùng để nút chèn vào, P nút cha N, G ông N, U bác N Giữa trường hợp, vai trò nhãn nút thay đổi cịn trường hợp khơng 4.2 Thêm node Phép chèn bắt đầu việc bổ sung nút tìm kiếm nhị phân bình thường gán cho màu đỏ Chú ý rằng: ● Tính chất “Tất -là nút null đen” giữ nguyên ● Tính chất “Cả hai nút đỏ đen” bị thay đổi việc thêm nút đỏ sửa cách gán màu đen cho nút đỏ phép quay ● Tính chất “Tất đường từ gốc tới có số nút đen” bị thay đổi việc thêm nút đỏ sửa cách gán màu đen cho nút đỏ phép quay Nút bác nút ông dễ dàng xác định nhờ hàm sau: struct node *grandparent(struct node *n) { return n->parent->parent; } struct node *uncle(struct node *n) { if (n->parent == grandparent(n)->left) return grandparent(n)->right; else return grandparent(n)->left; } ★ Trường hợp 1: Nút thêm N gốc Trong trường hợp này, gán lại màu đen cho N, để bảo tồn tính chất gốc đen void insert_case1(struct node *n) { 30 if (n->parent == NULL) n->color = BLACK; else insert_case2(n); } ★ Trường hợp 2: Nút cha P nút thêm đen, tính chất hai nút nút đỏ đen khơng bị vi phạm nút thêm có hai "null' đen Nút thêm đỏ không ảnh hưởng tới số nút đen tất đường void insert_case1(struct node *n) { if (n->parent == NULL) n->color = BLACK; else insert_case2(n); } ★ Trường hợp 3: Cả cha P bác U đỏ, đổi hai thành đen cịn G thành đỏ Khi nút N có cha đen Vì đường đi qua cha bác "N" phải qua ông N nên số nút đen đường khơng thay đổi Tuy nút ơng G vi phạm tính chất gốc đen hai nút đỏ nút đen Để sửa chữa trường hợp gọi thủ tục đệ quy G từ trường hợp Hình Thêm node trường hợp void insert_case3(struct node *n) { if (uncle(n)!= NULL && uncle(n)->color == RED) { n->parent->color = BLACK; uncle(n)->color = BLACK; grandparent(n)->color = RED; insert_case1(grandparent(n)); } else insert_case4(n); } Chú ý: Trong trường hợp tiếp theo, giả sử nút cha P trái cha Nếu phải, left right đổi chỗ cho trường hợp ★ Trường hợp 4: Nút cha P đỏ nút bác U đen, nút N phải nút P, P trái nút G Trong trường hợp này, thực quay trái chuyển đổi vai trò nút N nút cha P định dạng lại nút P Trường hợp (đổi vai trị N P) tính chất hai nút đỏ đen bị vi phạm Phép 31 quay làm thay đổi vài đường (các đường qua nhãn "1") phải qua thêm nút N, N đỏ Hình 4 Thêm node trường hợp void insert_case4(struct node *n) { if (n = = n->parent->right && n->parent = = grandparent(n)->left) { rotate_left(n->parent); n = n->left; } else if (n = = n->parent->left && n->parent = = grandparent(n)->right) { rotate_right(n->parent); n = n->right; } insert_case5(n); } ★ Trường hợp 5: Nút cha P đỏ nút bác U đen, nút N trái nút P, P trái nút ông G Trong trường hợp này, phép quay phải nút ông G thực hiện; kết phép quay nút P trở thành cha hai nút N nút G Đã biết G đen, P Đổi màu P G thỏa mãn tính chất hai nút đỏ đen Tính chất “Tất đường từ gốc tới có số nút đen” khơng bị vi phạm đường qua G trước qua P Hình Thêm node trường hợp void insert_case5(struct node *n) { n->parent->color = BLACK; grandparent(n)->color = RED; if (n == n->parent->left && n->parent == grandparent(n)->left) { rotate_right(grandparent(n)); } else { rotate_left(grandparent(n)); } 32 } 4.3 Xoá node Trong tìm kiếm nhị phân bình thường xóa nút có hai (khơng null), ta tìm phần tử lớn trái phần tử nhỏ phải, chuyển giá trị vào nút muốn xóa Khi xóa nút copy giá trị, nút có hai (khơng null) Vì việc copy giá trị khơng làm tính chất đỏ đen nên khơng cần phải sửa chữa cho thao tác Việc đặt xóa nút có nhiều (khơng null) Nếu ta xóa nút đỏ, ta chắn nút đen Tất đường đi qua nút bị xóa đơn giản bớt nút đỏ tính chất tất đường từ nút chứa số nút đen khơng thay đổi Ngồi ra, nút cha nút nút bị xóa nút đen, tính chất gốc đen hai nút đỏ đen nguyên Trường hợp phức tạp xảy nút bị xóa nút đen Chúng ta bắt đầu việc thay nút bị xóa nút Chúng ta gọi nút (trong vị trí N, anh em với (con khác nút cha mới) S Tiếp theo ta dùng P cha N, SL trái S, SR phải S (chúng tồn S khơng thể lá) Chú ý: Trong hình vẽ màu đỏ đen thể màu nút rõ ràng, màu trắng biểu thị màu chưa rõ (hoặc đỏ đen) Chúng ta sử dụng hàm sau tìm người anh em N: struct node *sibling(struct node *n) { if (n = = n->parent->left) return n->parent->right; else return n->parent->left; } Chú ý: Tất nhiên, cần hoàn chỉnh null sau phép thay đổi Nếu nút bị xóa khơng có N khác "lá null", dễ dàng thấy tính chất thỏa mãn Cịn N "lá nulll", sửa chữa lược đồ (hoặc code) để tất cảc trường hợp tính chất thỏa mãn Trước bước ta dùng hàm (function) replace_node thay nút child vào vị trí nút bị xóa Để thuận tiện đoạn code mục quy ước "lá null" biểu diễn đối tượng nút thực khác biệt chút với NULL (code phép chèn có biểu diễn khơng vậy) void delete_one_child(struct node *n) { /* Giả thiết: n có nút null */ struct node *child = is_leaf(n->right) ? n->left: n->right; replace_node(n, child); if (n->color == BLACK) { if (child->color == RED) child->color = BLACK; else 33 delete_case1(child); } free(n); } Ghi chú: Nếu N "lá nul" ta không muốn biểu diễn "lá null" đối tượng nút thực, ta sửa giải thuật cách trước hết gọi delete_case1() cha (nghĩa nút bị xóa n đoạn code trên) sau xóa Ta làm cha đen, có diễn biến với "lá null" (một số người gọi "lá ảo", "lá ma") Ta xóa khỏi cuối n khơi phục lại sau tất phép tốn Nếu N gốc ban đầu đen sau xóa đường qua "N" giảm bớt nút đen Do vi phạm tất đường từ nút chứa số nút đen, cần phải cân lại Có trường hợp sau: ★ Trường hợp 1: N gốc Trong trường hợp dừng lại Ta giải phóng nút đen khỏi đường gốc lại đen Khơng tính chất bị vi phạm void delete_case1(struct node *n) { if (n->parent == NULL) return; else delete_case2(n); } Chú ý: Trong trường hợp 2, 5, 6, ta quy ước N trái cha P Nếu phải, left right tráo đổi cho Tuy nhiên code ví dụ làm cho hai trường hợp ★ Trường hợp 2: S đỏ Trong trường hợp tráo đổi màu P S, sau quay trái P, làm cho S trở thành nút ông N Chú ý P có màu đen có màu đỏ Tất đường có số nút đen giống nhau, N có anh em màu đen cha màu đỏ, tiếp tục với trường hợp 4, 5, (anh em đen ví có nút đỏ S.) Trong trường hợp sau la gọi anh em N S Hình Xóa node trường hợp void delete_case2(struct node *n) { if (sibling(n)->color == RED) { n->parent->color = RED; sibling(n)->color = BLACK; 34 if (n == n->parent->left) rotate_left(n->parent); else rotate_right(n->parent); } delete_case3(n); } ★ Trường hợp 3: P, S, S đen Trong trường hợp này, gán lại cho S màu đỏ Kết đường qua S, (tất nhiên chúng khơng qua N,có nút đen Vì việc xóa cha trước N làm tất đương qua N bớt nút đen, nên chúng Tuy nhiên tất đường qua P có nút đen so với đường khơng qua P, tính chất tất đường từ gốc tới nút có số nút đen bị vi phạm Để sửa chữa lại tái cân P, trường hợp Hình Xóa node trường hợp void delete_case3(struct node *n) { if (n->parent->color == BLACK && sibling(n)->color == BLACK && sibling(n)->left->color == BLACK && sibling(n)->right->color == BLACK) { sibling(n)->color = RED; delete_case1(n->parent); } else delete_case4(n); } ★ Trường hợp 4: S S đen P đỏ Trong trường hợp này, đổi ngược màu S P Điều không ảnh hưởng tới số nút đen đường không qua N, thêm nút đen đường qua N, thay cho nút đen bị xóa đường void delete_case4(struct node *n) { if (n->parent->color == RED && sibling(n)->color == BLACK && sibling(n)->left->color == BLACK && sibling(n)->right->color == BLACK) { 35 sibling(n)->color = RED; n->parent->color = BLACK; } else delete_case5(n); } ★ Trường hợp 5: S đen, trái S đỏ, phải S đen, N trái cha Trong trường hợp quay phải S, trái S trở thành cha S N anh em Sau ta tráo đổi màu S cha Tất đường có số nút đen nhau, N có người anh em đen mà phải lại đỏ, chuyển sang Trường hợp Hoặc N cha bị tác động việc dịch chun Hình Xóa node trường hợp (Lưu ý trường hợp 6, ta đặt lại nút anh em N S.) void delete_case5(struct node *n) { if (n == n->parent->left && sibling(n)->color == BLACK && sibling(n)->left->color == RED && sibling(n)->right->color == BLACK) { sibling(n)->color = RED; sibling(n)->left->color = BLACK; rotate_right(sibling(n)); } else if (n == n->parent->right && sibling(n)->color == BLACK && sibling(n)->right->color == RED && sibling(n)->left->color == BLACK) { sibling(n)->color = RED; sibling(n)->right->color = BLACK; rotate_left(sibling(n)); } delete_case6(n); } ★ Trường hợp 6: S đen, phải S đỏ N trái nút cha P Trong trường hợp quay trái P, S trở thành cha P 36 phải S Chúng ta hoán đổi màu P S, gán cho phải S màu đen Cây giữ nguyên màu gốc Tính chất hai nút đỏ đen tính chất tất đường từ nút chứa số nút đen không bị vi phạm Tuy nhiên, N có thêm nút đen tiền nhiệm: P bị tô đen, đen S nút ơng trở thành đen Như cậy đương qua N có thêm nút đen Trong lúc đó, với đường khơng qua N, có hai khả năng: ● Đi qua nút anh em N Khi trước sau quay phải qua S P, thay đổi màu sắc hai nút tráo đổi màu cho Như vây đường không bị thay đổi số nút đen ● Đi qua nút bác N, phải S Khi trước quay qua S, cha S, phải S, sau quay qua nút S phải S, S nhận màu cũ cha P phải S đổi màu từ đỏ thành đen Kết số nút đen đường không thay đổi Như vậy, số nút đen đường khơng thay đổi Do tính chất hai nút đỏ đen tất đường từ nút chứa số nút đen khơi phục Nút trắng hình vẽ đỏ đen, phải ghi lại trước sau thay đổi Hình Xóa node trường hợp void delete_case6(struct node *n) { sibling(n)->color = n->parent->color; n->parent->color = BLACK; if (n == n->parent->left) { /* Here, sibling(n)->right->color == RED */ sibling(n)->right->color = BLACK; rotate_left(n->parent); } else { sibling(n)->left->color = BLACK; rotate_right(n->parent); } } 37 4.4 Áp dụng Trong Java, cấu trúc TreeMap, TreeSet xây dựng dựa Red-Black tree Từ Java 8, HashMap bucket chuyển đổi từ linked-list sang Red-Black tree để cải thiện performance trường hợp đụng độ hash C++ STL: map, multimap, multiset dùng Red-Black Tree Red-Black tree sử dụng nhiều Linux Kernel (Completely Fair Scheduler, CD/DVD driver, timer, ext3 filesystem, VMAs, ) 38 Tài liệu tham khảo: Lý thuyết mô AVL _ Nguyễn Thị Thu Hương _ AK54 _CNTT Cây AVL _ Nguyễn Mạnh Hiển _ Khoa Công nghệ thông tin _ hiennm@tlu.edu.vn https://www.stdio.vn/articles/phan-1-cay-nhi-phan-tim-kiem-457 https://cachhoc.net/2013/10/20/cay-mot-so-phep-toan-tren-cay-nhi-phan-tim-ki em/ http://doan.edu.vn/do-an/de-tai-cay-do-den-ly-thuyet-va-mo-phong-21995/ 39 Phân công thực hiện: Cả nhóm Đinh Thuý Chiều Nguyễn Thanh Thuỷ 4.Thiều Thị Ngọc Triệu 40 ... song Cây dùng từ năm 1857, nhà toán học Anh tên Authur Cayley dùng để xác định dạng khác hợp chất hố học Từ dùng để giải nhiều toán lĩnh vực khác Cây hay sử dụng tin học Chẳng hạn, người ta dùng... dụng tin học Trong khoa học máy tính cấu trúc liệu khơng tuyến tính Cấu trúc dùng để xây dựng thuật tốn có hiệu để định vị phần tử danh sách, ứng dụng giải thuật tìm kiếm, giải thuật xếp nhiều toán. .. diễn toán định (cây định), biểu diễn q trình tính tốn biểu thức đại số Vì đặc biệt có giá trị nghiên cứu toán xếp Các đặc biệt: (1) Cây nhị phân (2) Cây nhị phân tìm kiếm (Binary Search Trees