Bài giảng môn Cấu trúc dữ liệu - Chương 5: Cây (tree) cung cấp cho người học các kiến thức về khái niệm cây - Biểu diễn cây; cây nhị phân - Binary Tree (Định nghĩa, biểu diễn và các thao tác, cây nhị phân tìm kiếm (Binary Searching Tree)) cây cân bằng - Balanced Tree (Định nghĩa – Cấu trúc dữ liệu; các thao tác trên cây cân bằng). Mời các bạn cùng tham khảo nội dung chi tiết.
Chương 5: CÂY (TREE) 189 190 NỘI DUNG CHƯƠNG Khái niệm – Biểu diễn Cây nhị phân (Binary Tree) 3 Định nghĩa Biểu diễn thao tác Cây nhị phân tìm kiếm (Binary Searching Tree) Cây cân (Balanced Tree) Định nghĩa – Cấu trúc liệu Các thao tác cân BÀI TẬP 191 1.Khái niệm – Biểu diễn 1.1 Định nghĩa 1.2 Một số khái niệm liên quan 1.2.a Bậc 1.2.b Bậc nút 1.2.c Nút gốc 1.2.d Nút kết thúc 1.2.e Nút trung gian 1.2.f Mức nút 1.2.g Chiều cao (chiều sâu) 1.2.h Nút trước, nút sau nút 1.2.i Nút cha, nút nút 1.2.j Chiều dài đường nút 1.2.k Chiều dài đường 1.2.l Rừng 1.Khái niệm – Biểu diễn 1.1 Định nghĩa • Cây tập hợp phần tử (nút) tổ chức có đặc điểm • • • Hoặc tập hợp rỗng (cây rỗng) Hoặc tập hợp khác rỗng có nút làm nút gốc (Root’s Node), nút cịn lại phân thành nhóm nhóm (Sub-Tree) Các tập rỗng hay khác rỗng có nút gốc 192 193 1.Khái niệm – Biểu diễn 1.2 Một số khái niệm liên quan 1.2.a Bậc nút Bậc nút (node’s degree) số nút • 1.2.b Bậc Bậc (tree’s degree) bậc lớn • nút • Cây có bậc N gọi N-phân 1.2.c Nút gốc • Nút gốc (root’s tree) nút nút gốc khác (nút không làm gốc con) 194 1.Khái niệm – Biểu diễn 1.2.d Nút kết thúc Nút kết thúc hay gọi nút (leaf’s node) nút có bậc = (nút khơng có nút con) 1.2.e Nút trung gian • Nút trung gian hay cịn gọi nút (interior’s node) nút khơng phải nút gốc nút kết thúc (nút có bậc khác khơng nút gốc cây) 1.2.f Mức nút • Mức nút (node’s level) mức nút gốc chứa +1 • Mức nút gốc = 195 1.Khái niệm – Biểu diễn 1.2 Một số khái niệm liên quan (tt) 1.2.g Chiều cao (chiều sâu) • Chiều cao (chiều sâu) (tree’s height | tree’s depth) mức cao nút 1.2.h Nút trước, nút sau nút • Nút T gọi nút trước nút (ancestor’s node) nút S có gốc T chứa có gốc S Khi S gọi nút sau nút T (descendant’s node) 1.2.e Nút trung gian • Nút trung gian hay gọi nút (interior’s node) nút nút gốc nút kết thúc (nút có bậc khác khơng nút gốc cây) 196 1.Khái niệm – Biểu diễn 1.2 Một số khái niệm liên quan (tt) 1.2.f Mức nút • Mức nút (node’s level) mức nút gốc chứa +1 • Mức nút gốc = 1.2.g Chiều cao (chiều sâu) • Chiều cao (chiều sâu) (tree’s height | tree’s depth) mức cao nút 1.2.h Nút trước, nút sau nút Nút T gọi nút trước nút (ancestor’s node) • nút S có gốc T chứa có gốc S Khi S gọi nút sau nút T (descendant’s node) 197 1.Khái niệm – Biểu diễn 1.2 Một số khái niệm liên quan (tt) 1.2.i Nút cha, nút nút • Nút B gọi nút cha (parent’s node) nút C nút B nút trước nút B mức nút C lớn mức B mức Khi nút C gọi nút (child’s node) B 1.2.j Chiều dài đường nút • Chiều dài đường nút số đỉnh (số nút) tính từ nút gốc để đến nút • Chiều dài đường nút gốc = 1, chiều dài đường tới nút chiều dài đường tới nút cha + 198 1.Khái niệm – Biểu diễn 1.2 Một số khái niệm liên quan (tt) 1.2.k Chiều dài đường • Chiều dài đường (path’s length of the tree) tổng tất chiều dài đường tất nút (chiều dài đường internal path’s length) • Tính chiều dài đường (external path’s length) cách mở rộng tất nút cho nút có bậc (thêm vào nút giả) với bậc Chiều dài đường tổng chiều 1.2.l Rừng Rừng (forest) tập hợp • • Khi gốc rừng 214 Cây nhị phân (Binary Tree) 2.2 f Tính số nút Tính số nút tương tự tính chiều cao cây, số nút + Dùng cách tính đệ quy số nút B1: IF (BinTree == NULL) B1.1: NN = B1.2: Thực BKT B2: NNL = NN(BinTree->BinTLeft) B3: NNR = NN(BinTree->BinTRight) B4: NN = NNR + NNL + BKT: Kết thúc int BinTreeNumNode (BinTType BTree) { if (BTree == NULL) return (0); int NNL = BinTreeNumNode(BTree -> BinTLeft); int NNR = BinTreeNumNode(BTree -> BinTRight); return (NNL + NNR +1); } 215 Cây nhị phân (Binary Tree) 2.2 g Hủy nút nhị phân • Việc hủy nút làm cho trở thành rừng • Nếu tiến hành hủy nút khơng có vấn đề xảy • Nếu hủy nút khơng phải nút cần phải chuyển nút nút cần hủy qua nút khác tiến hành hủy • Nếu nút cần hủy có nút gốc chuyển nút gốc thành nút gốc cha nút cần hủy • Trong trường hợp nút cần hủy có nút gốc con, phải chuyển nút gốc thành nút gốc nút khác Tuỳ trường hợp cụ thể mà đưa cách chọn phù hợp 216 Cây nhị phân (Binary Tree) 2.3 Cây nhị phân tìm kiếm (Binary Searching Tree) 2.3.1 Khái niệm – Cấu trúc liệu • Cây nhị phân tìm kiếm nhị phân có thành phần khóa nút lớn tất thành phần khóa tất nút trái nhỏ thành phần khóa tất nút phải Cấu trúc liệu nhị phân tìm kiếm cấu trúc liệu biểu • diễn nhị phân nói chung typedef struct BSTNode { T Key; BSTNode * BSTLeft; BSTNode * BSTRight; } BSTOneNode; typedef BSTOneNode * BSTType; Để quản lý nhị phân tìm kiếm cần quản lý địa • nút gốc cây: BSTType BSTree; 217 Cây nhị phân (Binary Tree) 2.3 Cây nhị phân tìm kiếm (Binary Searching Tree) 2.3.1 Khái niệm – Cấu trúc liệu (tt) Khóa nhận diện tìm kiếm đơi khác (khơng • có tượng trùng khóa) • Nếu cần quản lý nút có khóa trùng nhị phân tìm kiếm mở rộng cấu trúc cách thêm thành phần Count ghi nhận số khóa trùng: typedef struct BSENode { T Key; int Count; BSENode * BSELeft; BSENode * BSERight; } BSEOneNode; typedef BSEOneNode * BSEType; • Nút bên trái nút có giá trị khóa nhận diện nhỏ nút phải nút có giá trị khóa nhận diện lớn • Trong BST, duyệt Left-Root-Right thứ tự duyệt theo tăng dần khóa nhận diện 218 Cây nhị phân (Binary Tree) 2.3 Cây nhị phân tìm kiếm (Binary Searching Tree) 2.3.2 Các thao tác nhị phân tìm kiếm 2.3.2.a Tìm kiếm 2.3.2.b Thêm vào nút 2.3.2.c Loại bỏ nút 2.3.2.d Hủy toàn 219 Cây nhị phân (Binary Tree) 2.3.2.a Tìm kiếm nhị phân tìm kiếm BST • Tìm kiếm có tồn nút có khóa (Key) SearchData hay khơng • Dùng thuật tốn tìm kiếm nhị phân đặc điểm nhị phân tìm kiếm nút nểu Key nút khác với SearchData: • • Nếu SearchData > Key nút tìm bên phải Nếu SearchData < Key nút tìm bên trái B1: CurrNode = BSTree B2: IF (CurrNode == NULL or CurrNode->Key == SearchData) Thực BKT B3: IF (CurrNode ->Key > SearchData) // tìm bên trái CurrNode = CurrNode->BSTree->BSTLeft B4: ELSE // tìm bên phải CurrNode = CurrNode->BSTree->BSTRight B5: Lặp lại B2 BKT: Kết thúc 220 Cây nhị phân (Binary Tree) 2.3.2.a Tìm kiếm nhị phân tìm kiếm BST (tt) Cài đặt thuật toán BSTType BSTSearching (BSTType BSTree, T SearchData) { BSTType CurrNode = BSTree; while (CurrNode !=NULL & CurrNode->Key != SeachData) { if (CurrNode ->Key > SearchData) CurrNode = CurrNode ->BSTLeft; else CurrNode = CurrNode ->BSTRight; } return (CurrNode); } 221 Cây nhị phân (Binary Tree) 2.3.2.b Thêm vào nút nhị phân tìm kiếm • Giả sử thêm vào nút có thành phần liệu NewData vào nhị phân tìm kiếm cho sau thêm, nhị phân tìm kiếm • Bao gồm thao tác tìm kiếm vị trí thêm thêm nút vào • Thao tác thêm khơng có tượng trùng khóa, NewData trùng với Key nút khơng thực thêm 222 Cây nhị phân (Binary Tree) 2.3.2.b Thêm vào nút nhị phân tìm kiếm (tt) B1: NewNode = BinTreeCreateNode(NewData) B2: IF(NewNode == NULL) Thực BKT B3: IF (BSTree == NULL) B3.1: BSTree = NewNode B3.2: Thực BKT B4: CurrNode = BSTree B5: IF (CurrNode == NULL) Thực BKT B6: IF (CurrNode->Key > NewData) B6.1: AddLeft = True B6.2: If (CurrNode->BSTLeft != NULL) CurrNode = CurrNode->BSTLeft B7: IF (CurrNode->Key < NewData) B6.1: AddLeft = False B6.2: If (CurrNode->BSTRight != NULL) CurrNode = CurrNode->BSTRight B8: Lặp lại B5 B9: IF (AddLeft == True) CurrNode = CurrNode->BSTLeft B10: ELSE CurrNode = CurrNode->BSTRight BKT: Kết thúc 223 Cây nhị phân (Binary Tree) 2.3.2.b Thêm vào nút nhị phân tìm kiếm (tt) BSTType BSTAddNode (BSTType &BSTree, T NewData) { BSTType NewNode = BinTreeCreateNode(NewData); if (NewNode == NULL) return (NewNode); if (BSTree == NULL) BSTree = NewNode; else { BSTType CurrNode = BSTree; int AddLeft = 1; while (CurrNode->Key != NewData) // khong them neu trung Key { if (CurrNode->Key > NewData) // them o cay ben trai { AddLeft = 1; if (CurrNode->BSTLeft != NULL) CurrNode = CurrNode->BSTLeft; else break; } else // them o cay ben phai { AddLeft = 0; if (CurrNode->BSTRight != NULL) CurrNode = CurrNode->BSTRight; else break; } } if (AddLeft == 1) CurrNode->BSTLeft = NewNode; else CurrNode->BSTRight = NewNode; } return (NewNode) } 224 Cây nhị phân (Binary Tree) 2.3.2.d Hủy toàn Thao tác đơn giản việc thực nhiều lần thao tác hủy nút nhị phân tìm kiếm trở thành rỗng Hàm thực việc hủy tất nút nhị phân tìm kiếm BSTree void BSTDelete(BSTType &BSTree) { BSTType DelNode = BSTree; while (BSTDeleteNodeTRS(BSTree, DelNode->Key) == 1) DelNode = BSTree; return; } 225 Cây cân (Balanced Tree) 3.1 Định nghĩa – Cấu trúc liệu Cây cân tương đối: • • • Là nhị phân thỏa mãn điều kiện nút chiều cao trái chiều cao phải nút khơng (theo định nghĩa Adelson-Velskii Landis) Cây cân tương đối gọi AVL (AVL Tree) Cây cân hồn tồn: • • • Là nhị phân thỏa mãn điều kiện nút số nút trái số nút phải nút khơng q Cây nhị phân cân hoàn toàn nhị phân cân tương đối 226 Cây cân (Balanced Tree) 3.1 Định nghĩa – Cấu trúc liệu (tt) • Để ghi nhận mức độ cân nút gốc con, dùng thêm thành phần Bal cấu trúc liệu nút typedef struct BALNode { T Key; int Bal; BALNode *BALLeft; BALNode *BALRight; }BALOneNode; typedef BALOneNode * BALType; • Để quản lý cân bằng, cần quản lý địa nút gốc BALType BALTree; 227 Cây cân (Balanced Tree) 3.1 Định nghĩa – Cấu trúc liệu (tt) • Giá trị số cân Bal nút gốc cân tương đối hiệu số chiều cao trái chiều cao phải nút • Giá trị số cân Bal nút gốc cân hoàn toàn = hiệu số số nút trái số nút phải nút • Nếu nút nhị phân mà thỏa mãn điều kiện -1 Key > SearchData) // tìm bên trái CurrNode = CurrNode->BSTree->BSTLeft B4: ELSE // tìm bên phải CurrNode = CurrNode->BSTree->BSTRight B5: Lặp