Chng III Cu trc cy Mc tiu FGii

  • Slides: 65
Download presentation
Chương III : Cấu trúc cây

Chương III : Cấu trúc cây

Mục tiêu FGiới thiệu khái niệm cấu trúc cây. FCấu trúc dữ liệu cây

Mục tiêu FGiới thiệu khái niệm cấu trúc cây. FCấu trúc dữ liệu cây nhị phân tìm kiếm: tổ chức, các thuật toán, ứng dụng. FGiới thiệu cấu trúc dữ liệu cây nhị phân tìm kiếm Caáu truùc Döõ lieäu - Caáu truùc caây 2

Cấu trúc cây

Cấu trúc cây

Cấu trúc cây Một số định nghĩa n n Định nghĩa 1: cây là

Cấu trúc cây Một số định nghĩa n n Định nghĩa 1: cây là một tập hợp T các phần tử (gọi là nút của cây) trong đó có 1 nút đặc biệt được gọi là gốc, các nút còn lại được chia thành những tập rời nhau T 1, T 2 , . . . , Tn theo quan hệ phân cấp trong đó Ti cũng là một cây. Mỗi nút ở cấp i sẽ quản lý một số nút ở cấp i+1. Quan hệ này người ta còn gọi là quan hệ cha-con. Định nghĩa 2: cấu trúc cây với kiểu cơ sở T là một nút cấu trúc rỗng được gọi là cây rỗng (NULL). Một nút mà thông tin chính của nó có kiểu T, nó liên kết với một số hữu hạn các cấu trúc cây khác cũng có kiểu cơ sở T. Các cấu trúc này được gọi là những cây con của cây đang xét. Caáu truùc Döõ lieäu - Caáu truùc caây 4

Cấu trúc cây Một số khái niệm cơ bản n n n Bậc của

Cấu trúc cây Một số khái niệm cơ bản n n n Bậc của một nút : là số cây con của nút đó Bậc của một cây : là bậc lớn nhất của các nút trong cây (số cây con tối đa của một nút thuộc cây ). Cây có bậc n thì gọi là cây n-phân. Nút gốc : là nút không có nút cha. Nút lá : là nút có bậc bằng 0. Nút nhánh : là nút có bậc khác 0 và không phải là gốc. Mức của một nút : ¨ Mức (gốc (T) ) = 0. ¨ Gọi T 1, T 2, T 3, . . . , Tn là các cây con của T 0 ¨ Mức (T 1) = Mức (T 2) =. . . = Mức (Tn) = Mức (T 0) + 1. Caáu truùc Döõ lieäu - Caáu truùc caây 5

Cấu trúc cây Một số khái niệm cơ bản n n Độ dài đường

Cấu trúc cây Một số khái niệm cơ bản n n Độ dài đường đi từ gốc đến nút x : là số nhánh cần đi qua kể từ gốc đến x Độ dài đường đi tổng của cây : trong đó Px là độ dài đường đi từ gốc đến X. Độ dài đường đi trung bình : PI = PT/n (n là số nút trên cây T). Rừng cây: là tập hợp nhiều cây trong đó thứ tự các cây là quan trọng. Caáu truùc Döõ lieäu - Caáu truùc caây 6

Khái niệm Cạnh nút Z B Q Caáu truùc Döõ lieäu - Caáu truùc

Khái niệm Cạnh nút Z B Q Caáu truùc Döõ lieäu - Caáu truùc caây gốc J A R K D A F L Lá 7

Cấu trúc cây Một số ví dụ về đối tượng các cấu trúc dạng

Cấu trúc cây Một số ví dụ về đối tượng các cấu trúc dạng cây n Sơ đồ tổ chức của một công ty BB-Electronic Corp. R&D Kinh doanh Noäi ñòa Chaâu Caáu truùc Döõ lieäu - Caáu truùc caây Saûn xuaát Taøi vuï Quoác teá Myõ TV CD Amplier Caùc nöôùc 8

Cấu trúc cây Một số ví dụ về đối tượng các cấu trúc dạng

Cấu trúc cây Một số ví dụ về đối tượng các cấu trúc dạng cây n Mục lục một quyển sách Student guide Giôùi thieäu Baøi taäp Caáu truùc Döõ lieäu - Caáu truùc caây Ñieåm Thöïc haønh Moâi tröôøng NN LT CT maãu Thi 9

Cấu trúc cây @Nhận xét: ¨ Trong cấu trúc cây không tồn tại chu

Cấu trúc cây @Nhận xét: ¨ Trong cấu trúc cây không tồn tại chu trình ¨ Tổ chức 1 cấu trúc cây cho phép truy cập nhanh đến các phần tử của nó. Caáu truùc Döõ lieäu - Caáu truùc caây 10

Cây nhị phân

Cây nhị phân

Cây nhị phân n Định nghĩa: Cây nhị phân là cây mà mỗi nút

Cây nhị phân n Định nghĩa: Cây nhị phân là cây mà mỗi nút có tối đa 2 cây con n Trong thực tế thường gặp các cấu trúc có dạng cây nhị phân. Một cây tổng quát có thể biểu diễn thông qua cây nhị phân. Caáu truùc Döõ lieäu - Caáu truùc caây 12

Cây nhị phân Cây con trái Cây con phải Hình ảnh một cây nhị

Cây nhị phân Cây con trái Cây con phải Hình ảnh một cây nhị phân Caáu truùc Döõ lieäu - Caáu truùc caây 13

Cây nhị phân n Cây nhị phân dùng để biểu diễn một biểu thức

Cây nhị phân n Cây nhị phân dùng để biểu diễn một biểu thức toán học: Caáu truùc Döõ lieäu - Caáu truùc caây 14

Cây nhị phân Một số tính chất của cây nhị phân n Số nút

Cây nhị phân Một số tính chất của cây nhị phân n Số nút nằm ở mức i n Chiều cao cây h là mức cao nhất + 1. Số nút lá 2 h-1, với h là chiều cao của cây. Chiều cao của cây h log 2(số nút trong cây). Số nút trong cây 2 h-1. n n Mức Đường đi (path) ¨ Tên các node của quá trình đi từ node gốc theo các cây con đến một node nào đó. Caáu truùc Döõ lieäu - Caáu truùc caây 15

Cây nhị phân Biểu diễn cây nhị phân T n Cây nhị phân là

Cây nhị phân Biểu diễn cây nhị phân T n Cây nhị phân là một cấu trúc bao gồm các phần tử (nút) được kết nối với nhau theo quan hệ “cha-con” với mỗi cha có tối đa 2 con. Để biểu diễn cây nhị phân ta chọn phương pháp cấp phát liên kết. Ứng với một nút, ta sử dụng một biến động lưu trữ các thông tin sau: ¨ Thông tin lưu trữ tại nút. ¨ Địa chỉ nút gốc của cây con trái trong bộ nhớ. ¨ Địa chỉ nút gốc của cây con phải trong bộ nhớ. Caáu truùc Döõ lieäu - Caáu truùc caây 16

Cây nhị phân Để đơn giản, ta khai báo cấu trúc dữ liệu như

Cây nhị phân Để đơn giản, ta khai báo cấu trúc dữ liệu như sau : typedef struct NODE { int data; NODE* left; NODE* right; }; typedef struct NODE* TREE; TREE root; Caáu truùc Döõ lieäu - Caáu truùc caây 17

Tạo cây nhị phân void Create. Tree(TREE &root) { int x; printf(“n. Gia tri

Tạo cây nhị phân void Create. Tree(TREE &root) { int x; printf(“n. Gia tri node : ”); x=toupper(getch()); if(isspace(x)==0) { root=(node*)malloc(sizeof(node)); root ->data=x; printf(“n. Con trai cua %c (ENTER NULL)”, x); Create. Tree(root->left); (root printf(“n. Con phai cua %c (ENTER NULL)”, x); Create. Tree(root->right); (root } else root=NULL; } Caáu truùc Döõ lieäu - Caáu truùc caây 18

Cây nhị phân Duyệt cây nhị phân n Có 3 kiểu duyệt chính có

Cây nhị phân Duyệt cây nhị phân n Có 3 kiểu duyệt chính có thể áp dụng trên cây nhị phân: ¨ Duyệt theo thứ tự trước (NLR) ¨ Duyệt theo thứ tự giữa (LNR) ¨ Duyệt theo thứ tựï sau (LRN). n Tên của 3 kiểu duyệt này được đặt dựa trên trình tự của việc thăm nút gốc so với việc thăm 2 cây con. Caáu truùc Döõ lieäu - Caáu truùc caây 19

Cây nhị phân Duyệt theo thứ tự trước (Node-Left-Right) n n Kiểu duyệt này

Cây nhị phân Duyệt theo thứ tự trước (Node-Left-Right) n n Kiểu duyệt này trước tiên thăm nút gốc sau đó thăm các nút của cây con trái rồi đến cây con phải. Thủ tục duyệt có thể trình bày đơn giản như sau: void NLR(TREE root) { if (Root != NULL) { <Xử lý Root>; //Xử lý tương ứng theo nhu cầu NLR(root->left); NLR(root->right); } } Caáu truùc Döõ lieäu - Caáu truùc caây 20

Cây nhị phân Duyệt theo thứ tự trước (Node-Left-Right) n Một ví dụ: đọc

Cây nhị phân Duyệt theo thứ tự trước (Node-Left-Right) n Một ví dụ: đọc một quyển sách hay bài báo từ đầu đến cuối như minh họa trong hình bên dưới: Caáu truùc Döõ lieäu - Caáu truùc caây 21

Duyệt theo thứ tự trước (Node-Left-Right) A B C D E H I N

Duyệt theo thứ tự trước (Node-Left-Right) A B C D E H I N J F G K O L M P Kết quả: A B D H I N E J O K C F L P G M Caáu truùc Döõ lieäu - Caáu truùc caây 22

Cây nhị phân Duyệt theo thứ tự giữa (Left- Node-Right) n n Kiểu duyệt

Cây nhị phân Duyệt theo thứ tự giữa (Left- Node-Right) n n Kiểu duyệt này trước tiên thăm các nút của cây con trái sau đó thăm nút gốc rồi đến cây con phải. Thủ tục duyệt có thể trình bày đơn giản như sau: void LNR(TREE root) { if (root != NULL) { LNR(root->left); <Xử lý Root>; //Xử lý tương ứng theo nhu cầu LNR(root->right); } } Caáu truùc Döõ lieäu - Caáu truùc caây 23

Duyệt theo thứ tự giữa (Left- Node-Right) A B C D E H I

Duyệt theo thứ tự giữa (Left- Node-Right) A B C D E H I N J F G K O L M P Kết quả: H D N I B J O E K A F P L C M G Caáu truùc Döõ lieäu - Caáu truùc caây 24

Cây nhị phân Duyệt theo thứ tự sau (Left-Right-Node) n n Kiểu duyệt này

Cây nhị phân Duyệt theo thứ tự sau (Left-Right-Node) n n Kiểu duyệt này trước tiên thăm các nút của cây con trái sau đó thăm đến cây con phải rồi cuối cùng mới thăm nút gốc. Thủ tục duyệt có thể trình bày đơn giản như sau: void LRN(TREE root) { if (root != NULL) { LRN(root->left); LRN(root->right); <Xử lý Root>; //Xử lý tương ứng theo nhu cầu } } Caáu truùc Döõ lieäu - Caáu truùc caây 25

Cây nhị phân Duyệt theo thứ tự sau (Left-Right-Node) n Một ví dụ quen

Cây nhị phân Duyệt theo thứ tự sau (Left-Right-Node) n Một ví dụ quen thuộc trong tin học về ứng dụng của duyệt theo thứ tự sau là việc xác định tồng kích thước của một thư mục trên đĩa Caáu truùc Döõ lieäu - Caáu truùc caây 26

Duyệt theo thứ tự sau (Left-Right-Node) A B C D E H I N

Duyệt theo thứ tự sau (Left-Right-Node) A B C D E H I N J F G K O L M P Kết quả: H N I D O J K E B P L F M G C A Caáu truùc Döõ lieäu - Caáu truùc caây 27

Cây nhị phân Duyệt theo thứ tự sau (Left-Right-Node) n Tính toán giá trị

Cây nhị phân Duyệt theo thứ tự sau (Left-Right-Node) n Tính toán giá trị của biểu thức dựa trên cây biểu thức (3 + 1) 3/(9 – 5 + 2) – (3 (7 – 4) + 6) = – 13 Caáu truùc Döõ lieäu - Caáu truùc caây 28

Cây nhị phân Biểu diễn cây tổng quát bằng cây nhị phân n Nhược

Cây nhị phân Biểu diễn cây tổng quát bằng cây nhị phân n Nhược điểm của các cấu trúc cây tổng quát: ¨ Bậc của các nút trên cây có thể dao động trong một biên độ lớn việc biểu diễn gặp nhiều khó khăn và lãng phí. ¨ Việc xây dựng các thao tác trên cây tổng quát phức tạp n hơn trên cây nhị phân nhiều. Vì vậy, thường nếu không quá cần thiết phải sử dụng cây tổng quát, người ta chuyển cây tổng quát thành cây nhị phân. Caáu truùc Döõ lieäu - Caáu truùc caây 29

Cây nhị phân Biểu diễn cây tổng quát bằng cây nhị phân n Ta

Cây nhị phân Biểu diễn cây tổng quát bằng cây nhị phân n Ta có thể biến đổi một cây bất kỳ thành một cây nhị phân theo qui tắc sau: ¨ Giữ lại nút con trái nhất làm nút con trái. ¨ Các nút con còn lại chuyển thành nút con phải. ¨ Như vậy, trong cây nhị phân mới, con trái thể hiện quan hệ cha con và con phải thể hiện quan hệ anh em trong cây tổng quát ban đầu. Caáu truùc Döõ lieäu - Caáu truùc caây 30

Cây nhị phân Biểu diễn cây tổng quát bằng cây nhị phân n Giả

Cây nhị phân Biểu diễn cây tổng quát bằng cây nhị phân n Giả sử có cây tổng quát như hình bên dưới: A B E Caáu truùc Döõ lieäu - Caáu truùc caây F C G H D I J 31

Cây nhị phân Biểu diễn cây tổng quát bằng cây nhị phân n A

Cây nhị phân Biểu diễn cây tổng quát bằng cây nhị phân n A Cây nhị phân tương ứng sẽ như sau: B E C H F G D I J Caáu truùc Döõ lieäu - Caáu truùc caây 32

Cây nhị phân Một cách biểu diễn cây nhị phân khác n n Đôi

Cây nhị phân Một cách biểu diễn cây nhị phân khác n n Đôi khi, khi định nghĩa cây nhị phân, người ta quan tâm đến cả quan hệ 2 chiều cha con chứ không chỉ một chiều như định nghĩa ở phần trên. Lúc đó, cấu trúc cây nhị phân có thể định nghĩa lại như sau: typedef struct tag. TNode { Data. Type Key; struct tag. TNode* p. Parent; struct tag. TNode* p. Left; struct tag. TNode* p. Right; }TNODE; typedef TNODE *TREE; Caáu truùc Döõ lieäu - Caáu truùc caây 33

Cây nhị phân Một cách biểu diễn cây nhị phân khác Caáu truùc Döõ

Cây nhị phân Một cách biểu diễn cây nhị phân khác Caáu truùc Döõ lieäu - Caáu truùc caây 34

Cây nhị phân tìm kiếm

Cây nhị phân tìm kiếm

Cây nhị phân tìm kiếm n n n Trong chương 3, chúng ta đã

Cây nhị phân tìm kiếm n n n Trong chương 3, chúng ta đã làm quen với một số cấu trúc dữ liệu động. Các cấu trúc này có sự mềm dẻo nhưng lại bị hạn chế trong việc tìm kiếm thông tin trên chúng (chỉ có thể tìm kiếm tuần tự). Nhu cầu tìm kiếm là rất quan trọng. Vì lý do này, người ta đã đưa ra cấu trúc cây để thỏa mãn nhu cầu trên. Tuy nhiên, nếu chỉ với cấu trúc cây nhị phân đã định nghĩa ở trên, việc tìm kiếm còn rất mơ hồ. Cần có thêm một số ràng buộc để cấu trúc cây trở nên chặt chẽ, dễ dùng hơn. Một cấu trúc như vậy chính là cây nhị phân tìm kiếm. Caáu truùc Döõ lieäu - Caáu truùc caây 36

Cây nhị phân tìm kiếm n Định nghĩa: cây nhị phân tìm kiếm (CNPTK)

Cây nhị phân tìm kiếm n Định nghĩa: cây nhị phân tìm kiếm (CNPTK) là cây nhị phân trong đó tại mỗi nút, khóa của nút đang xét lớn hơn khóa của tất cả các nút thuộc cây con trái và nhỏ hơn khóa của tất cả các nút thuộc cây con phải. n Nếu số nút trên cây là N thì chi phí tìm kiếm trung bình chỉ khoảng log 2 N. Caáu truùc Döõ lieäu - Caáu truùc caây 37

Cây nhị phân tìm kiếm 44 18 88 13 15 Caáu truùc Döõ lieäu

Cây nhị phân tìm kiếm 44 18 88 13 15 Caáu truùc Döõ lieäu - Caáu truùc caây 59 37 23 40 55 108 71 38

Thêm một nút vào cây int Insert. Tree(tree &root , int x) { if(root

Thêm một nút vào cây int Insert. Tree(tree &root , int x) { if(root != NULL) { if(root->data==x) return 0; if(root->data>x) return Insert. Tree(root->letf, x); else return Insert. Tree(root->right, x); } else { root=(node*)malloc(sizeof(node); if(root !=NULL) return -1; root->data=x; root->left=root->right=NULL; return 1; } } Caáu truùc Döõ lieäu - Caáu truùc caây 39

Tạo cây nhị phân tìm kiếm n Ta có thể tạo một cây nhị

Tạo cây nhị phân tìm kiếm n Ta có thể tạo một cây nhị phân tìm kiếm bằng cách lặp lại quá trình thêm 1 phần tử vào một cây rỗng. void Create. Tree(tree &root) { int x, n; printf(“Nhap n = “); scanf(“%d”, &n); for(int i=1; i<=n; i++) { scanf(“%d”, &x); Insert. Tree(root, x); } } Caáu truùc Döõ lieäu - Caáu truùc caây 40

Tạo cây nhị phân tìm kiếm 25 37 10 18 29 50 3 1

Tạo cây nhị phân tìm kiếm 25 37 10 18 29 50 3 1 6 5 12 20 35 13 32 41 25 10 37 3 18 1 6 12 5 25 37 10 18 Caáu truùc Döõ lieäu - Caáu truùc caây 29 20 35 13 29 50 50 41 32 3 1 6 5 12 20 35 13 32 41 41

Duyệt cây nhị phân tìm kiếm n n Thao tác duyệt cây trên cây

Duyệt cây nhị phân tìm kiếm n n Thao tác duyệt cây trên cây nhị phân tìm kiếm hoàn toàn giống như trên cây nhị phân. Lưu ý: khi duyệt theo thứ tự giữa, trình tự các nút duyệt qua sẽ cho ta một dãy các nút theo thứ tự tăng dần của khóa. Caáu truùc Döõ lieäu - Caáu truùc caây 42

Tìm một phần tử x trong cây (đệ quy) n Tìm một phần tử

Tìm một phần tử x trong cây (đệ quy) n Tìm một phần tử x trong cây (đệ quy): TNODE* search. Node(TREE root, Data X) { if(root->data == X) return root; if(root->data > X) return search. Node(root->left, X); return search. Node(root->right, X); } return NULL; } Caáu truùc Döõ lieäu - Caáu truùc caây 43

Tìm một phần tử x trong cây (không đệ quy) n Tìm một phần

Tìm một phần tử x trong cây (không đệ quy) n Tìm một phần tử x trong cây (không đệ quy): TNODE * search. Node(TREE root, Data x) { TNODE *p = root; while (p != NULL) { if(x == p->data) return p; else if(x < p->data) p = p->left; else p = p->right; } return NULL; } Caáu truùc Döõ lieäu - Caáu truùc caây 44

Tìm một phần tử x=13 trong cây 25 10 37 3 18 1 6

Tìm một phần tử x=13 trong cây 25 10 37 3 18 1 6 5 12 29 20 13 50 35 41 32 Giống Node gốc nhau nhỏ hơn lớn hơn Khác nhau Tìm kiếm 13 Caáu truùc Döõ lieäu - Caáu truùc caây Tìm thấy Số node duyệt: 5 Số lần so sánh: 9 45

Tìm một phần tử x=13 trong cây 25 10 37 3 18 1 6

Tìm một phần tử x=13 trong cây 25 10 37 3 18 1 6 5 12 29 20 13 50 35 41 32 Giống Node gốc nhau nhỏ hơn lớn hơn Khác nhau Tìm kiếm 13 Caáu truùc Döõ lieäu - Caáu truùc caây Tìm thấy Số node duyệt: 5 Số lần so sánh: 9 46

Tìm một phần tử x trong cây @Nhận xét: ¨ Số lần so sánh

Tìm một phần tử x trong cây @Nhận xét: ¨ Số lần so sánh tối đa phải thực hiện để tìm phần tử X là h, với h là chiều cao của cây. ¨ Như vậy thao tác tìm kiếm trên CNPTK có n nút tốn chi phí trung bình khoảng O(log 2 n). Caáu truùc Döõ lieäu - Caáu truùc caây 47

Tìm một phần tử x trong cây 44 Tìm X=55 44 < X 18

Tìm một phần tử x trong cây 44 Tìm X=55 44 < X 18 13 37 15 Caáu truùc Döõ lieäu - Caáu truùc caây 88 88 > X 23 59 59 > X 40 55 108 71 48

Thêm một phần tử x vào cây n Thêm một phần tử x vào

Thêm một phần tử x vào cây n Thêm một phần tử x vào cây: ¨ Việc thêm một phần tử X vào cây phải bảo đảm điều kiện ràng buộc của CNPTK. Ta có thể thêm vào nhiều chỗ khác nhau trên cây, nhưng nếu thêm vào một nút ngoài sẽ là tiện lợi nhất do ta có thể thực hiên quá trình tương tự thao tác tìm kiếm. Khi chấm dứt quá trình tìm kiếm cũng chính là lúc tìm được chỗ cần thêm. ¨ Hàm insert trả về giá trị – 1, 0, 1 khi không đủ bộ nhớ, gặp nút cũ hay thành công: Caáu truùc Döõ lieäu - Caáu truùc caây 49

Thêm một phần tử x vào cây int insert. Node(TREE &root, Data X) {

Thêm một phần tử x vào cây int insert. Node(TREE &root, Data X) { if (root) { if(root->data == X) return 0; // đã có if(root->data > X) return insert. Node(root->left, X); else return insert. Node(root->right, X); } root = new Node; if (root == NULL) return -1; // thiếu bộ nhớ root->data = X; root->left = root->right = NULL; return 1; // thêm vào thành công } Caáu truùc Döõ lieäu - Caáu truùc caây 50

Thêm một phần tử x vào cây 44 Theâm X=50 44 < X 18

Thêm một phần tử x vào cây 44 Theâm X=50 44 < X 18 13 37 15 88 88 > X 23 59 59 > X 40 55 108 71 55 > X 50 Caáu truùc Döõ lieäu - Caáu truùc caây 51

Hủy một phần tử có khóa x n n Việc hủy một phần tử

Hủy một phần tử có khóa x n n Việc hủy một phần tử X ra khỏi cây phải bảo đảm điều kiện ràng buộc của CNPTK. Có 3 trường hợp khi hủy nút X có thể xảy ra: ¨ X là nút lá. ¨ X chỉ có 1 con (trái hoặc phải). ¨ X có đủ cả 2 con Caáu truùc Döõ lieäu - Caáu truùc caây 52

Hủy một phần tử có khóa x Trường hợp 1: X là nút lá.

Hủy một phần tử có khóa x Trường hợp 1: X là nút lá. 1. Xóa node này 2. Gán liên kết từ cha của nó thành rỗng Caáu truùc Döõ lieäu - Caáu truùc caây 53

Hủy một phần tử có khóa x Trường hợp 1: X là nút lá.

Hủy một phần tử có khóa x Trường hợp 1: X là nút lá. n Ví dụ : chỉ đơn giản hủy X vì nó không móc nối đến phần tử nào khác. 44 T/h 1: huûy X=40 18 88 13 15 Caáu truùc Döõ lieäu - Caáu truùc caây 59 37 23 40 55 108 71 54

Hủy một phần tử có khóa x Trường hợp 2: X chỉ có 1

Hủy một phần tử có khóa x Trường hợp 2: X chỉ có 1 con (trái hoặc phải) Gán liên kết từ cha của nó xuống con duy nhất của nó 2. Xóa node này 1. u u x v v Caáu truùc Döõ lieäu - Caáu truùc caây 55

Hủy một phần tử có khóa x Trường hợp 2: X chỉ có 1

Hủy một phần tử có khóa x Trường hợp 2: X chỉ có 1 con (trái hoặc phải) n Trường hợp thứ hai: trước khi hủy X ta móc nối cha của X với con duy nhất của nó 44 T/h 2: huûy X=37 18 88 13 15 Caáu truùc Döõ lieäu - Caáu truùc caây 59 37 23 55 108 71 56

Hủy một phần tử có khóa x Trường hợp 3: X có đủ 2

Hủy một phần tử có khóa x Trường hợp 3: X có đủ 2 con 1. Tìm w là node trước node x trên phép duyệt cây inorder (chính là node cực phải của cây con bên trái của x) 2. Thay x bằng w 3. Xóa node w cũ (giống trường hợp 1 hoặc 2 đã xét) Caáu truùc Döõ lieäu - Caáu truùc caây 57

Hủy một phần tử có khóa x Trường hợp 3: X có đủ 2

Hủy một phần tử có khóa x Trường hợp 3: X có đủ 2 con n Trường hợp cuối cùng: ¨ Không thể hủy trực tiếp do X có đủ 2 con ¨ Hủy gián tiếp: n Thay vì hủy X, ta sẽ tìm một phần tử thế mạng Y. Phần tử này có tối đa một con. n Thông tin lưu tại Y sẽ được chuyển lên lưu tại X. n Sau đó, nút bị hủy thật sự sẽ là Y giống như 2 trường hợp đầu. ¨ Vấn đề: chọn Y sao cho khi lưu Y vào vị trí của X, cây vẫn là CNPTK. Caáu truùc Döõ lieäu - Caáu truùc caây 58

Hủy một phần tử có khóa x Trường hợp 3: X có đủ 2

Hủy một phần tử có khóa x Trường hợp 3: X có đủ 2 con n n Vấn đề là phải chọn Y sao cho khi lưu Y vào vị trí của X, cây vẫn là CNPTK. Có 2 phần tử thỏa mãn yêu cầu: ¨ Phần tử nhỏ nhất (trái nhất) trên cây con phải. ¨ Phần tử lớn nhất (phải nhất) trên cây con trái. Việc chọn lựa phần tử nào là phần tử thế mạng hoàn toàn phụ thuộc vào ý thích của người lập trình. Ở đây, ta sẽ chọn phần tử phải nhất trên cây con trái làm phân tử thế mạng. Caáu truùc Döõ lieäu - Caáu truùc caây 59

Hủy một phần tử có khóa x Trường hợp 3: X có đủ 2

Hủy một phần tử có khóa x Trường hợp 3: X có đủ 2 con n Khi hủy phần tử X=18 ra khỏi cây, phần tử 23 là phần tử thế mạng: 44 T/h 3: huûy X=18 18 88 13 15 Caáu truùc Döõ lieäu - Caáu truùc caây 59 37 23 40 30 55 108 71 60

Hủy một phần tử có khóa x Trường hợp 3: X có đủ 2

Hủy một phần tử có khóa x Trường hợp 3: X có đủ 2 con n Hàm del. Node trả về giá trị 1, 0 khi hủy thành công hoặc không có X trong cây: int del. Node(TREE &root, Data X) n Hàm search. Stand. For tìm phần tử thế mạng cho nút p void search. Stand. For(TREE &p, TREE &q) Caáu truùc Döõ lieäu - Caáu truùc caây 61

Hủy một phần tử có khóa x int del. Node(TREE &root, Data X) {

Hủy một phần tử có khóa x int del. Node(TREE &root, Data X) { if(root== NULL) return 0; if(root->data > X) return del. Node(root->left, X); if(root->data < X) return del. Node(root->right, X); //T->Key == X Node* p = root; if(root->left == NULL) root = root->right; else if(root->right == NULL) root = root->left; else // T cĩ dủ 2 con search. Stand. For(p, root->right); delete p; } Caáu truùc Döõ lieäu - Caáu truùc caây 62

Hủy một phần tử có khóa x void search. Stand. For(TREE &p, TREE &q)

Hủy một phần tử có khóa x void search. Stand. For(TREE &p, TREE &q) { if(q->left) search. Stand. For(p, q->left); else { p->data = q->data; p = q; q = q->right; } } Caáu truùc Döõ lieäu - Caáu truùc caây 63

Hủy toàn bộ cây nhị phân tìm kiếm n Việc toàn bộ cây có

Hủy toàn bộ cây nhị phân tìm kiếm n Việc toàn bộ cây có thể được thực hiện thông qua thao tác duyệt cây theo thứ tự sau. Nghĩa là ta sẽ hủy cây con trái, cây con phải rồi mới hủy nút gốc. void remove. Tree(TREE &root) { if(root) { remove. Tree(root->reft); remove. Tree(root->right); delete(root); } } Caáu truùc Döõ lieäu - Caáu truùc caây 64

Cây nhị phân tìm kiếm @Nhận xét: ¨ Tất cả các thao tác search.

Cây nhị phân tìm kiếm @Nhận xét: ¨ Tất cả các thao tác search. Node, insert. Node, del. Node đều có độ phức tạp trung bình O(h), với h là chiều cao của cây ¨ Trong trường hợp tốt nhất, CNPTK có n nút sẽ có độ cao h = log 2(n). Chi phí tìm kiếm khi đó sẽ tương đương tìm kiếm nhị phân trên mảng có thứ tự. ¨ Trong trường hợp xấu nhất, cây có thể bị suy biến thành 1 danh sách liên kết (khi mà mỗi nút đều chỉ có 1 con trừ nút lá). Lúc đó các thao tác trên sẽ có độ phức tạp O(n). ¨ Vì vậy cần có cải tiến cấu trúc của CNPTK để đạt được chi phí cho các thao tác là log 2(n). Caáu truùc Döõ lieäu - Caáu truùc caây 65