Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 26 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
26
Dung lượng
229,87 KB
Nội dung
Kỹ thuật lập trì nh 105 CHươNG 6 cácthuậttoántrêncấutrúccâY (Tree) Câ y là một cấ u trúc dữ liệ u rấ t thông dụng và quan trọng trong nhiề u phạ m vi khá c nhau của kỹ thuậ t má y tí nh. Ví dụ : Tổ chức cá c quan hệ họ hà ng trong một gia phả , mục lục của một cuốn sá ch, xâ y dựng cấ u trúc về cú phá p trong cá c trì nh biê n dịch. Trong chương trì nh nà y, chúng ta khả o sá t cá c khá i niệ m cơ bả n về câ y, cá c phép toá n trê n câ y nhị phâ n, cũng như cá c phép toá n trê n câ y nhị phâ n câ n bằ ng ( AVL tree) và ứng dụng của hai loạ i câ y nhị phâ n tì m kiế m (BST), câ y nhị phâ n câ n bằ ng ( AVL tree). I. Phân loại cây : I.1. Một số khái niệ m cơ bản : 1. Cây : Câ y là tậ p hợp cá c phầ n tử gọi là nút, một nút (tương tự như một phầ n tử của d y) có thể có kiể u bấ t kỳ. Cá c nút đ ược biể u diễ n bởi 1 ký tự chữ, một chuỗi, một số ghi trong một vòng tròn. Một số định nghĩ a theo đệ quy ( Một nút đơn cũng chí nh là một câ y. ( Cá c nút đ ược gọi là ở cùng một câ y khi có đ ường đi giữa cá c nút nà y. ( Một câ y sẽ bao gồm một nút gốc (Root) và m câ y con, trong mỗi câ y con lạ i có một nút gốc và m1 câ y con nhỏ hơn v.v. ( Một câ y không có một nút nà o cả gọi là câ y rỗng. Ví dụ 1 : A B C G H E J D F KI 1 2 3 4 Nuựt goỏc Hì nh 5.1. Câ y với nút gốc là A - A là nút gốc với 3 câ y con lầ n lượt có 3 nút gốc riê ng là ứ B, C, D - Nút cha (ancestor) Nút con (descendent) A là nút cha của B, C, D G, H là nút con của C G, H không quan hệ cha con với A Kỹ thuật lập trì nh 106 Ví dụ 2 : Với đề cương một môn học T, ta có thể biể u diễ n dạ ng câ y như sau : T CHệễNG I CHệễNG II CHệễNG III I.1 I.2 II.1 II.3II.2 II.1.1 II.1.2 Hì nh 5.2 CHươNG I I.1 I.2 CHươNG II II.1 II.1.1 II.1.2 II.2 II.3 CHươNG III 2. Nút cha (Ancestor) : Nút đứng trê n của một nút đ ược gọi là nút cha C là nút cha của G, H Nút con (descendent) : Nút đứng sau một nút khá c đ ược gọi là nút con của nút đó. Nút I, J, K là nút con của nút E 3. Bậc (degree) : - Bậ c của nút là số câ y con của nút đó. C có bậ c là 2, E có bậ c là 3 (Hì nh 5.1) - Bậ c của câ y là bậ c lớn nhấ t của cá c nút trong câ y. Câ y trong hì nh 5.1 có bậ c là 3. Câ y bậ c n đ ược gọi là câ y n phâ n như câ y nhị phâ n, câ y tam phâ n. 4. Nút lá và nút trung gian : - Nút lá là nút có bậ c bằ ng 0 (tức là không có câ y con nà o) : - Nút trung gian: là một nút có bậ c khá c 0 và không phả i là nút gốc. Ví dụ : Trong hì nh 5.1, B, G, H, I, J, K, F là nút lá C, D, E là nút trung gian. 5. Mức của nút (level) : Nút gốc có mức là 1 Mức của nút con = mức của nút cha + 1 Kỹ thuật lập trì nh 107 Ví dụ: trong hì nh 5.1, A có mức là 1 B, C, D có mức là 2 G, H, E, F có mức là 3 I, J, K có mức là 4 6. Chiề u cao của cây (height) : là mức lớn nhấ t của cá c nút lá trong câ y. Ví dụ : Câ y trong hì nh 5.1 có chiề u cao là 4 7. Thứ tự của các nút (order of nodes) : Nế u câ y đ ược gọi là có thứ tự thì phả i đả m bả o vị trí của cá c nút con từ trái qua phả i, tức là nế u thay đổi vị trí của một nút con bấ t kỳ thì ta đ có một câ y mới. Ví dụ : A B C A C B caõy khaực Hì nh 5.3: Sau khi đổi vị trí của 2 nút B, C ta đ có câ y mới. 8. Chiề u dài đường đi (Path length): - Chiề u dà i đ ường đi của nút x: là số cá c cạ nh đi từ nút gốc đế n nút x. Ví dụ : Trong hì nh 5.1: Nút gốc A có chiề u dà i đ ường đi là 1 Nút B, C, D có chiề u dà i đ ường đi là 2 Tổng quá t : một nút tạ i mức i có chiề u dà i đ ường đi là i - Chiề u dà i đ ường đi của câ y: là tổng của cá c chiề u dà i đường đi của tấ t cả cá c nút trong câ y. Ví dụ : Chiề u dà i đ ường đi của câ y trong hì nh 5.1 là 31. Chiề u dà i đ ường đi trung bì nh của câ y: n/)i. n ( P i ii = trong đó n i là số cá c nút ở mức i và n là tổng số cá c nút trong câ y. I.2. Cách biể u diễ n cây : để biể u diễ n 1 câ y, ta có nhiề u cá ch như biể u diễ n bằ ng đồ thị,bằ ng giả n đồ, bằ ng chỉ số Nhưng thông thường, ta hay dùng dạ ng đồ thị để biểu diễn 1 câ y như hì nh 5.1 I.3. Biể u diễ n thứ tự các nút trong cây : Kỹ thuật lập trì nh 108 Một câ y thường tổ chức cá c nút theo một thứ tự nhấ t định că n cứ và o một nội dung gọi là khóa của cá c nút. Có thể tổ chức câ y có khóa tă ng dầ n theo mức từ trá i qua phả i như ví dụ sau : 1 2 3 4 Root 76 8 5 9 ROOT %1%2%3%4%5%6%7%8%9 Như vậ y khi duyệ t lạ i câ y theo mức tă ng dầ n và từ trá i qua phả i ta sẽ lạ i có đ ược thứ tự cá c nút như trê n. Hì nh 5.4. Câ y có thứ tự tă ng dầ n theo mức từ trá i qua phả i II. Cây nhị phân (Binary tree) II.1. Định nghĩ a : 1. Cây nhị phân là câ y có bậ c bằ ng 2, tức là số nút con tối đa của một nút bấ t kỳ trong câ y là 2. Câ y nhị phâ n có thể là một câ y rỗng (không có nút nà o) hoặ c câ y chỉ có một nút, hoặ c câ y chỉ có cá c nút con bê n trá i (Left Child) hoặ c nút con bê n phả i (Right Child) hoặ c cả hai. Ví dụ : Hì nh 5.4 là câ y nhị phâ n. 2. Cáccây nhị phân đặc biệ t: - Câ y nhị phâ n đúng : Một câ y nhị phâ n đ ược gọi là câ y nhị phâ n đúng nế u nút gốc và tấ t cả cá c nút trung gian đề u có 2 nút con. A B D E G Y C X F H I Hì nh 5.5. Câ y nhị phâ n đúng Kỹ thuật lập trì nh 109 Ghi chú: nế u câ y nhị phâ n đúng có n nút lá thì câ y nà y sẽ có tấ t cả 2n-1 nút. - Câ y nhị phâ n đầ y : Một câ y nhị phâ n gọi là câ y nhị phâ n đầ y với chiề u cao d thì : . Nó phả i là câ y nhị phâ n đúng và . Tấ t cả cá c nút lá đề u có mức là d. Hì nh 5.5 không phả i là câ y nhị phâ n đầ y A B D H I E J K C F L M G N O Hì nh 5.6. Câ y nhị phâ n đầ y. Ghi chú : Câ y nhị phâ n đầ y là câ y nhị phâ n có số nút tối đa ở mỗi mức. - Câ y nhị phâ n tì m kiế m (Binary Search Tree): Một câ y nhị phâ n gọi là câ y nhị phâ n tì m kiế m nế u và chỉ nế u đối với mọi nút của câ y thì khóa của một nút bấ t kỳ phả i lớn hơn khóa của tấ t cả cá c nút trong câ y con bê n trá i của nó và phả i nhỏ hơn khóa của tấ t cả cá c nút trong câ y con bê n phả i của nó. Ví dụ : 8 7 9 3 12 11 102 1 5 4 6 k 1 <k 1 <k 1 Hì nh 5.7. Câ y nhị phâ n tì m kiế m (BST) Kỹ thuật lập trì nh 110 - Câ y nhị phâ n câ n bằ ng (AVL): Một câ y nhị phâ n đ ược gọi là câ y nhị phâ n câ n bằ ng nế u và chỉ nế u đối với mọi nút của câ y thì chiề u cao của câ y con bê n trá i và chiề u cao của câ y con bê n phả i hơn kém nhau nhiề u nhấ t là 1. (Theo Adelson-Velski và Landis). A C E F B D G I J H Hì nh 5.8. Câ y nhị phâ n câ n bằ ng - Câ y nhị phâ n câ n bằ ng hoà n toà n : Một câ y nhị phâ n đ ược gọi là câ y nhị phâ n câ n bằ ng hoà n toà n nế u và chỉ nế u đối với mọi nút của câ y thì số nút của câ y con bê n trá i và số nút của câ y con bê n phả i hơn kém nhau nhiề u nhấ t là 1. A C E F B D I H E H Hì nh5.9. Câ y nhị phâ n câ n bằ ng hoà n toà n 3. Các phép duyệ t cây nhị phân (Traverse) : là quá trì nh đi qua cá c nút đúng một lầ n. Khi duyệ t câ y, ta thường dùng 3 cá ch duyệ t cơ bả n sau : ' Preorder - Tiề n tự (NLR) duyệ t qua nút gốc trước, sau đó đi qua câ y con bê n trá i lạ i á p dụng Preorder cho câ y con bê n trá i. Cuối cùng qua câ y con bê n phả i, á p dụng Preorder cho câ y con bê n phả i. Ví dụ : Theo câ y nhị phâ n 5.4, ta có: ROOT % 1 % 2 % 3 % 4 % 6 % 7 % 5 % 8 % 9 'Inorder - Trung tự (LNR) : qua câ y con bê n trá i duyệ t trước (theo thứ tự LNR), sau đó thă m nút gốc. Cuối cùng qua câ y con bê n phả i (theo thứ tự LNR) Ví dụ : Theo câ y nhị phâ n 5.4, ta có: ROOT % 2 % 1 % 6 % 4 % 7 % 3 % 8 % 5 % 9 'Postorder - Hậ u tự (LRN) : qua câ y con bê n trá i duyệ t trước (theo thứ tự LRN), sau đó qua câ y con bê n phả i (theo thứ tự LRN). Cuối cùng thă m nút gốc. Ví dụ : Theo câ y nhị phâ n 5.4, ta có: ROOT % 2 % 6 % 7 % 4 % 8 % 9 % 5 % 3 % 1 Kỹ thuật lập trì nh 111 Ghi chú : Đối với câ y ta có thể tổ chức thứ tự theo khóa là một nội dung của nút hoặ c ta đặ t thê m 1 field gọi là khóa của nút . II.2. Các phép toán trê n cây nhị phân : - Khai báo : Để tổ chức dữ liệ u theo câ y nhị phâ n, ta có thể dùng một nội dung của dữ liệ u để là m khóa sắ p xế p và tổ chức câ y theo nhiề u cá ch khá c nhau. Nhưng thông thường để thuậ n tiệ n cho việ c tì m kiế m và thực hiệ n cá c phép toá n khá c trê n câ y, người ta tạ o thê m một khóa riê ng trong cá c phầ n tử và tạ o ra câ y nhị phâ n tì m kiế m. Để khai bá o biế n tree quả n lý một câ y nhị phâ n, với nội dung info chứa số nguyê n, ta khai bá o như sau: struct nodetype { int key; int info; struct nodetype *left; struct nodetype *right; }; typedef struct nodetype *NODEPTR; NODEPTR tree; 1. Tạo cây: a. Khởi tạ o câ y (Initialize): dùng để khởi động câ y nhị phâ n, cho chương trì nh hiể u là hiệ n tạ i câ y nhị phâ n rỗng. void Initialize(NODEPTR &root) { root = NULL; } Lời gọi hà m : Initialize(tree); b. Cấ p phá t vùng nhớ (New_Node): cấ p phá t một nút cho câ y nhị phâ n. Hà m New_Node nà y trả về địa chỉ của nút vừa cấ p phá t. NODEPTR New_Node(void) { NODEPTR p; p = (NODEPTR)malloc(sizeof(struct nodetype)); return(p); } Lời gọi hà m : p= New_Node(); Kỹ thuật lập trì nh 112 c. Tạ o câ y BST (Create_Tree): Trong giả i thuậ t tạ o câ y BST, ta có dùng hà m Insert. Hà m Insert : dùng phương phá p đệ qui thê m nút có khóa x, nội dung a và o câ y có nút gốc root . Câ y nhị phâ n tạ o đ ược qua giả i thuậ t Create_Tree là câ y nhị phâ n tì m kiế m (BST). void Insert(NODEPTR root, int x, int a) { NODEPTR p; if(x == root->key) // khóa bị trùng, dừng chương trì nh { printf("bi trung khoa, khong them nut nay duoc"); return; } if(x < root->info && root->left == NULL) // điề u kiệ n dừng giả i thuậ t đệ qui { p = New_Node(); // cấ p phá t vùng nhớ p->key =x; p->info = a; p->left = NULL; p->right = NULL; root->left=p; return; } if(x > root->info && root->right == NULL) //điề u kiệ n dừng giả i thuậ t đệ qui { p = New_Node(); p->key =x; p->info = a; p->left = NULL; p->right = NULL; root->right=p ; return; } if(x < root->info) // bước đệ qui Insert(root->left, x,a); // gọi đệ qui qua nhá nh trá i else Insert(root->right, x,a); // gọi đệ qui qua nhá nh phả i } Kỹ thuật lập trì nh 113 void Create_Tree(NODEPTR &root) { int khoa, noidung; char so[10]; NODEPTR p; do { printf("Nhap khoa :"); gets(so) ; khoa = atoi(so); if (khoa !=0) { printf("Nhap noi dung :"); gets(so) ; noidung = atoi(so); if (root==NULL) { p = New_Node(); p->key = khoa; p->info = noidung; p->left = NULL; p->right = NULL; root =p; } else Insert(root,khoa,noidung); } } while (khoa!=0); // khóa =0 thì dừng nhậ p } Ghi chú : Để tạ o câ y nhị phâ n do biế n tree quả n lý, ta gọi: Create_Tree(tree); 2. Cập nhật cây: a. Giả i phóng vùng nhớ (Free_Node): giả i phóng vùng nhớ mà p đang trỏ đế n. void Free_Node(NODEPTR p) { free(p); } Lời gọi hà m : Free_Node (p); b. Kiể m tra câ y nhị phâ n rỗng hay không (Empty): hà m Empty trả về TRUE nế u câ y nhị phâ n rỗng, và ngược lạ i. int Empty(NODEPTR root) return(root == NULL ? TRUE : FALSE); } Kỹ thuật lập trì nh 114 Lời gọi hà m: Empty(tree) c. Hủy bỏ một nút trong câ y nhị phâ n BST (Remove): Xóa nút có khóa là x trong câ y nhị phâ n tì m kiế m sao cho sau khi xóa thì câ y nhị phâ n vẫ n là câ y nhị phâ n tì m kiế m. Ta có 3 trường hợp : - Trường hợp 1 : nút p cầ n xóa là nút lá . Việ c xóa nút p chỉ đơn giả n là hủy nút p p1 p p1 p1 p p1 - Trường hợp 2 : Nút p cầ n xóa có 1 câ y con, thì ta cho rp chỉ tới nút p. Sau đó, ta tạ o liê n kế t từ nút cha của p tới nút con của rp, cuối cùng hủy nút p. 10 5 3 15 12 20 2 4 p xoựa nuựt p 10 3 15 12 20 2 4 rp Hì nh 5.10. Xóa nút p trong trường hợp nút nà y có 1 câ y con bê n trá i. 2 10 5 3 15 4 20 18 25 rp p xoựa nuựt p 10 5 3 20 18 25 2 4 Hì nh 5.11. Xóa nút p trong trường hợp nút nà y có 1 câ y con bê n phả i. - Trường hợp 3 : Nút p cầ n xóa có 2 câ y con. Ta cho rp chỉ tới nút p. Do tí nh chấ t nút cực trá i của câ y con bê n phả i của p có khóa vừa lớn hơn khóa của p, nê n để loạ i p thì ta sẽ cho r chỉ tới nút cực trá i đó. Sau đó, ta sao chép nội dung . Kỹ thuật lập trì nh 105 CHươNG 6 các thuật toán trên cấu trúc câY (Tree) Câ y là một cấ u trúc dữ liệ u rấ t thông dụng và. vào cây AVL làm cây mất cân bằng, đó là thê m các nút vào sau bê n trái của nút có cf = 1, và thê m các nút vào sau bê n phải của nút có cf = -1. Kỹ thuật