Cấu trúc dữ liệu và giải thuật II - Chương 3 docx

28 393 0
Cấu trúc dữ liệu và giải thuật II - Chương 3 docx

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

CHƯƠNG - CÂY ĐỎ ĐEN Trong chương tìm hiểu phần sau đây: 1.Giới thiệu 2.Định nghĩa đỏ đen 3.Phép quay 4.Thêm node 5.Loại bỏ node 6.Tính hiệu đỏ đen 7.Cài đặt Thảo luận cân Tóm tắt GIỚI THIỆU Cây tìm kiếm nhị phân thơng thường có thuận lợi lớn mặt lưu trữ truy xuất liệu phép tốn tìm kiếm thêm vào hay loại bỏ phần tử Do đó, tìm kiếm nhị phân xem cấu trúc lưu trữ liệu tốt Tuy nhiên số trường hợp tìm kiếm nhị phân có số hạn chế Nó hoạt động tốt liệu chèn vào theo thứ tự ngẫu nhiên Tuy nhiên, liệu chèn vào theo thứ tự đuợc xếp không hiệu Khi trị số cần chèn đuợc xếp nhị phân trở nên không cân Khi không cân bằng, khả tìm kiếm nhanh (hoặc chèn xóa) phần tử cho Chúng ta khảo sát cách giải vấn đề khơng cân bằng: đỏ đen, tìm kiếm nhị phân có thêm vài đặc điểm Có nhiều cách tiếp cận khác để bảo đảm cho cân bằng: chẳng hạn 2-3-4 Tuy vậy, phần lớn trường hợp, đỏ đen cân hiệu nhất, liệu lưu trữ nhớ tập tin Trước khảo sát đỏ đen, xem lại không cân tạo Hình 3.1 Các node chèn theo thứ tự tăng dần Những node tự xếp thành đường khơng phân nhánh Bởi node lớn node chèn vào trước đó, node phải Khi ấy, bị cân hoàn toàn Nếu ta chèn mục (item) theo thứ tự giảm dần, node trái node cha chúng - bị cân phía bên Độ phức tạp: Khi nhánh, trở thành danh sách liên kết, liệu chiều thay hai chiều Trong trường hợp này, thời gian truy xuất giảm O(N), thay O(logN) cân Để bảo đảm thời gian truy xuất nhanh O(logN) cây, cần phải bảo đảm ln ln cân (ít gần cân bằng) Điều có nghĩa node phải có xấp xỉ số node bên phải số node bên trái Một cách tiếp cận giải vấn đề cân lại cây: đỏ đen-là tìm kiếm nhị phân bổ sung số đắc điểm Trong đỏ đen, việc cân thực thi chèn, xóa Khi thêm phần tử thủ tục chèn kiểm tra xem tính chất cân có bị vi phạm hay khơng Nếu có, xây dựng lại cấu trúc Bằng cách này, luôn giữ cân ĐỊNH NGHĨA CÂY ĐỎ ĐEN Cây đỏ đen nhị phân tìm kiếm( BST) tuân thủ quy tắc sau: (hình 3.2) Mọi node phải đỏ đen Node gốc node phải luôn đen Nếu node đỏ, node phải đen Mọi đường dẫn từ gốc đến phải có số lượng node đen Khi chèn (hay xóa) node mới, cần phải tuân thủ quy tắc -gọi quy tắc đỏ đen Nếu tuân thủ, cân Hình 3.2 Một ví dụ đỏ đen Số lượng node đen đường dẫn từ gốc đến gọi chiều cao đen (black height) Ta phát biểu quy tắc theo cách khác đường dẫn từ gốc đến phải có chiều cao đen Bổ đề: Một đỏ đen n-node Có: height right */ x->right = y->left; if (y->left != NIL) y->left->parent = x; /* Thiết lập liên kết y->parent */ if (y != NIL) y->parent = x->parent; if (x->parent) { if (x == x->parent->left) x->parent->left = y; else x->parent->right = y; } else { root = y; } /* link x and y */ y->left = x; if (x != NIL) x->parent = y; } static void rotateRight(NodeType *x) { /**************************** * Xoay node x bên phải * ****************************/ NodeType *y = x->left; /* Thiết lập liên kết x->left */ x->left = y->right; if (y->right != NIL) y->right->parent = x; /* Thiết lập liên kết y->parent */ if (y != NIL) y->parent = x->parent; if (x->parent) { if (x == x->parent->right) x->parent->right = y; else x->parent->left = y; } else { root = y; } /* liên kết x y */ y->right = x; if (x != NIL) x->parent = y; } /************************************* * Chương trình thêm node x vào đỏ đen* *************************************/ static void insertFixup(NodeType *x) { /* Kiểm tra thuộc tính đỏ đen */ while (x != root && x->parent->color == RED) { /* we have a violation */ if (x->parent == x->parent->parent->left) { NodeType *y = x->parent->parent->right; if (y->color == RED) { /* bác RED */ x->parent->color = BLACK; y->color = BLACK; x->parent->parent->color = RED; x = x->parent->parent; } else { /* bác BLACK */ if (x == x->parent->right) { /* tạo x trái*/ x = x->parent; rotateLeft(x); } /* đổi màu xoay */ x->parent->color = BLACK; x->parent->parent->color = RED; rotateRight(x->parent->parent); } } else { /* Tương tự */ NodeType *y = x->parent->parent->left; if (y->color == RED) { /* bác is RED */ x->parent->color = BLACK; y->color = BLACK; x->parent->parent->color = RED; x = x->parent->parent; } else { /* bác BLACK */ if (x == x->parent->left) { x = x->parent; rotateRight(x); } } x->parent->color = BLACK; x->parent->parent->color = RED; rotateLeft(x->parent->parent); } } root->color = BLACK; } /*********************************************** * Cấp phát thêm vào * ***********************************************/ StatusEnum insert(KeyType key, RecType *rec) { NodeType *current, *parent, *x; /Tìm cha mới*/ current = root; parent = 0; while (current != NIL) { if (compEQ(key, current->key)) return STATUS_DUPLICATE_KEY; parent = current; current = compLT(key, current->key) ? current->left : current->right; } /* Thiết lập node */ if ((x = malloc (sizeof(*x))) == 0) return STATUS_MEM_EXHAUSTED; x->parent = parent; x->left = NIL; x->right = NIL; x->color = RED; x->key = key; x->rec = *rec; /* Thêm node */ if(parent) { if(compLT(key, parent->key)) parent->left = x; else parent->right = x; } else { root = x; } insertFixup(x); return STATUS_OK; } /************************************* * Chương trình loại bỏ node x * *************************************/ void deleteFixup(NodeType *x) { while (x != root && x->color == BLACK) { if (x == x->parent->left) { NodeType *w = x->parent->right; if (w->color == RED) { w->color = BLACK; x->parent->color = RED; rotateLeft (x->parent); w = x->parent->right; } if (w->left->color == BLACK && w->right->color == BLACK) { w->color = RED; x = x->parent; } else { if (w->right->color == BLACK) { w->left->color = BLACK; w->color = RED; rotateRight (w); w = x->parent->right; } w->color = x->parent->color; x->parent->color = BLACK; w->right->color = BLACK; rotateLeft (x->parent); x = root; } } else { NodeType *w = x->parent->left; if (w->color == RED) { w->color = BLACK; ... */ if (x->parent == x->parent->parent->left) { NodeType *y = x->parent->parent->right; if (y->color == RED) { /* bác RED */ x->parent->color = BLACK; y->color = BLACK; x->parent->parent->color... x->parent; } else { if (w->right->color == BLACK) { w->left->color = BLACK; w->color = RED; rotateRight (w); w = x->parent->right; } w->color = x->parent->color; x->parent->color = BLACK; w->right->color... x->parent->right; if (w->color == RED) { w->color = BLACK; x->parent->color = RED; rotateLeft (x->parent); w = x->parent->right; } if (w->left->color == BLACK && w->right->color == BLACK) { w->color

Ngày đăng: 22/07/2014, 14:21

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan