840 likes | 1.18k Views
TREES (Cấu trúc cây). Mục tiêu. Giới thiệu khái niệm cấu trúc cây . Cấ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 . Giới thiệu cấu trúc dữ liệu cây nhị phân tìm kiếm. Cấu trúc cây. Cấu trúc cây.
E N D
Mụctiêu • Giớithiệukháiniệmcấutrúccây. • Cấutrúcdữliệucâynhịphântìmkiếm: tổchức, cácthuậttoán, ứngdụng. • Giớithiệucấutrúcdữliệucâynhịphântìm kiếm Caáu truùc Döõ lieäu - Caáu truùc caây
Cấutrúccây • Địnhnghĩa :câylàmộttậphợpTcácphầntử (gọilànútcủacây) trongđócó 1 nútđặcbiệtđượcgọilàgốc, cácnútcònlạiđượcchiathànhnhữngtậprờinhauT1, T2 , ... , TntheoquanhệphâncấptrongđóTicũnglàmộtcây. Mỗinút ở cấpisẽquảnlýmộtsốnút ở cấpi+1. Quanhệnàyngườitacòngọilàquanhệcha-con. Caáu truùc Döõ lieäu - Caáu truùc caây
Cấutrúccây Caáu truùc Döõ lieäu - Caáu truùc caây
Cấutrúccây Caáu truùc Döõ lieäu - Caáu truùc caây
CấutrúccâyMộtsốkháiniệmcơbản • Bậccủamộtnút :làsốcâyconcủanútđó • Bậccủamộtcây :làbậclớnnhấtcủacácnúttrongcây (sốcâycontốiđacủamộtnútthuộccây ). Câycóbậcnthìgọilàcâyn-phân. • Nútgốc :lànútkhôngcónútcha. • Nútlá :lànútcóbậcbằng 0 . • Nútnhánh :lànútcóbậckhác 0 vàkhôngphảilàgốc . • Mứccủamộtnút : • Mức (gốc (T) ) = 0. • GọiT1, T2, T3, ... , TnlàcáccâyconcủaT0 • Mức (T1) = Mức (T2) = ... = Mức (Tn) = Mức (T0) + 1. Caáu truùc Döõ lieäu - Caáu truùc caây
CấutrúccâyMộtsốkháiniệmcơbản • Độdàiđườngđitừgốcđếnnútx :làsốnhánhcầnđiquakểtừgốcđếnx • Độdàiđườngđitổngcủacây : trongđóPxlàđộdàiđườngđitừgốcđếnX. • Độdàiđườngđitrungbình : PI = PT/n (nlàsốnúttrêncâyT). • Rừngcây:làtậphợpnhiềucâytrongđóthứtựcáccâylàquantrọng. Caáu truùc Döõ lieäu - Caáu truùc caây
Khái niệm gốc J Cạnh nút Z A B R D Q K A F L Lá Caáu truùc Döõ lieäu - Caáu truùc caây
BB-Electronic Corp. R&D Kinh doanh Taøi vuï Saûn xuaát Noäi ñòa Quoác teá TV CD Amplier Chaâu aâu Myõ Caùc nöôùc CấutrúccâyMộtsốvídụvềđốitượngcáccấutrúcdạngcây • Sơđồtổchứccủamộtcôngty Caáu truùc Döõ lieäu - Caáu truùc caây
Student guide Giôùi thieäu Ñieåm Moâi tröôøng NN LT CT maãu Baøi taäp Thöïc haønh Thi CấutrúccâyMộtsốvídụvềđốitượngcáccấutrúcdạngcây • Mụclụcmộtquyểnsách Caáu truùc Döõ lieäu - Caáu truùc caây
Cấutrúccây • Nhậnxét: • Trongcấutrúccâykhôngtồntạichutrình Caáu truùc Döõ lieäu - Caáu truùc caây
Câynhịphân • Địnhnghĩa: Câynhịphânlàcâymàmỗinútcótốiđa 2 câycon • Trongthựctếthườnggặpcáccấutrúccódạngcâynhịphân. Mộtcâytổngquátcóthểbiểudiễnthôngquacâynhịphân. Caáu truùc Döõ lieäu - Caáu truùc caây
Cây con trái Cây con phải Hình ảnh một cây nhị phân Câynhịphân Caáu truùc Döõ lieäu - Caáu truùc caây
Câynhịphân Figure 7.3: Binary tree structure. Caáu truùc Döõ lieäu - Caáu truùc caây
Câynhịphân Figure 7.4: Skewed trees. Caáu truùc Döõ lieäu - Caáu truùc caây
Câynhịphân • Câynhịphândùngđểbiểudiễnmộtbiểuthứctoánhọc: Caáu truùc Döõ lieäu - Caáu truùc caây
CâynhịphânMộtsốtínhchấtcủacâynhịphân • Sốnútnằm ở mứci • Chiều cao cây h là mức cao nhất + 1. • Sốnútlá 2h-1, vớihlàchiềucaocủacây. • Chiềucaocủacâyhlog2(sốnúttrongcây). • Sốnúttrongcây 2h-1. • Đườ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 đó. Mức Caáu truùc Döõ lieäu - Caáu truùc caây
CâynhịphânBiểudiễncâynhịphânT • Câynhịphânlàmộtcấutrúcbaogồmcácphầntử (nút) đượckếtnốivớinhautheoquanhệ“cha-con”vớimỗichacótốiđa 2 con. Đểbiểudiễncâynhịphântachọnphươngphápcấpphátliênkết. Ứngvớimộtnút, tasửdụngmộtbiếnđộnglưutrữcácthôngtinsau: • Thôngtinlưutrữtạinút. • Địachỉnútgốccủacâycontráitrongbộnhớ. • Địachỉnútgốccủacâyconphảitrongbộnhớ. Caáu truùc Döõ lieäu - Caáu truùc caây
Câynhịphân Caáu truùc Döõ lieäu - Caáu truùc caây
Câynhị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
CâynhịphânDuyệtcâynhịphân • Có3kiểuduyệtchínhcóthểápdụngtrêncâynhịphân: • Duyệttheothứtựtrước (NLR)- Preorder • Duyệttheothứtựgiữa (LNR)- Inorder • Duyệttheothứtựïsau (LRN)- Postorder • Têncủa3kiểuduyệtnàyđượcđặtdựatrêntrìnhtựcủaviệcthămnútgốcsovớiviệcthăm 2 câycon. Caáu truùc Döõ lieäu - Caáu truùc caây
CâynhịphânDuyệttheothứtựtrước (Node-Left-Right) • Kiểuduyệtnàytrướctiênthămnútgốcsauđóthămcácnútcủacâycontráirồiđếncâyconphải. • Thủtụcduyệtcóthểtrìnhbàyđơngiảnnhưsau: voidNLR(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
CâynhịphânDuyệttheothứtựtrước (Node-Left-Right) • Mộtvídụ: đọcmộtquyểnsáchhaybàibáotừđầuđếncuốinhưminhhọatronghìnhbêndưới: Caáu truùc Döõ lieäu - Caáu truùc caây
Duyệt theo thứ tự trước (Node-Left-Right) A B C D E F G H I J K L M N O P M Kết quả: A B D H I N E J O K C F L P G Caáu truùc Döõ lieäu - Caáu truùc caây
Cây nhị phân Duyệt theo thứ tự giữa (Left- Node-Right) • 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
Duyệt theo thứ tự giữa (Left- Node-Right) A B C D E F G H I J K L M N O P G Kết quả: H D N I B J O E K A F P L C M Caáu truùc Döõ lieäu - Caáu truùc caây
Cây nhị phân Duyệt theo thứ tự sau (Left-Right-Node) • 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
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 Cây nhị phân Duyệt theo thứ tự sau (Left-Right-Node) Caáu truùc Döõ lieäu - Caáu truùc caây
Duyệt theo thứ tự sau (Left-Right-Node) A B C D E F G H I J K L M N O P A Kết quả: H N I D O J K E B P L F M G C Caáu truùc Döõ lieäu - Caáu truùc caây
(3 + 1)3/(9 – 5 + 2) – (3(7 – 4) + 6) = –13 CâynhịphânDuyệttheothứtựsau (Left-Right-Node) • Tínhtoángiátrịcủabiểuthứcdựatrêncâybiểuthức Caáu truùc Döõ lieäu - Caáu truùc caây
CâynhịphânMộtcáchbiểudiễncâynhịphânkhác • Đôikhi, khiđịnhnghĩacâynhịphân, ngườitaquantâmđếncảquanhệ 2 chiềuchaconchứkhôngchỉmộtchiềunhưđịnhnghĩa ở phầntrên. • Lúcđó, cấutrúccâynhịphâncóthểđịnhnghĩalạinhưsau: typedefstructtagTNode { DataType Key; structtagTNode* pParent; structtagTNode* pLeft; structtagTNode* pRight; }TNODE; typedefTNODE *TREE; Caáu truùc Döõ lieäu - Caáu truùc caây
CâynhịphânMộtcáchbiểudiễncâynhịphânkhác Caáu truùc Döõ lieäu - Caáu truùc caây
Câynhịphântìmkiếm (BST) • Địnhnghĩa: câynhịphântìmkiếm (BST) làcâynhịphântrongđótạimỗinút, khóacủanútđangxétlớnhơnkhóacủatấtcảcácnútthuộccâycontráivànhỏhơnkhóacủatấtcảcácnútthuộccâyconphải. • NếusốnúttrêncâylàNthìchiphítìmkiếmtrungbìnhchỉkhoảnglog2N. Caáu truùc Döõ lieäu - Caáu truùc caây
44 18 88 59 108 13 37 15 23 40 55 71 Câynhịphântìmkiếm Caáu truùc Döõ lieäu - Caáu truùc caây
Cấu trúc dữ liệu 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
Các thao tác trên BST a. Khởi tạo cây BST Khởi tạo cây BST: cho con trỏ quản lý địa chỉ nút gốc về con trỏ NULL void Init(Node &root) { root = NULL; } Caáu truùc Döõ lieäu - Caáu truùc caây
Các thao tác trên BST Tạo node: Node* GetNode (int x) { p= new Node; if (p != NULL) { p-> Left = NULL; p-> Right = NULL; p-> Data = x; } return (p); } Caáu truùc Döõ lieäu - Caáu truùc caây
Thêm một nút vào cây BST int InsertTree(tree &root , int x) { if(root != NULL) { if(root->data==x) return 0; if(root->data>x) return InsertTree(root->letf,x); else returnInsertTree(root->right,x); } else Caáu truùc Döõ lieäu - Caáu truùc caây
else { root= new 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
Tạo cây nhị phân tìm kiếm • 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 CreateTree(tree &root) { int x,n; cout<<“Nhap n = “; cin>>n; for(int i=1; i<=n;i++) { cout<<“Nhap gia tri:”; cin>>x; InsertTree(root,x); } } Caáu truùc Döõ lieäu - Caáu truùc caây
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 29 50 1 6 12 20 35 41 5 13 32 25 37 10 18 29 50 3 1 6 5 12 20 35 13 32 41 Caáu truùc Döõ lieäu - Caáu truùc caây
Duyệtcâynhịphântìmkiếm • Thaotácduyệtcâytrêncâynhịphântìmkiếmhoàntoàngiốngnhưtrêncâynhịphân. • Lưuý: khiduyệttheothứtựgiữa, trìnhtựcácnútduyệtquasẽchotamộtdãycácnúttheothứtựtăngdầncủakhóa. Caáu truùc Döõ lieäu - Caáu truùc caây
Duyệtcâynhịphântìmkiếm • Duyệt theo thứ tự trước – (Node-Left-Right): Duyệt nút gốc, duyệt cây con bên trái, duyệt cây con bên phải voidNLR(TREE root) { if (root!=NULL) { cout<<root->data<<" "; NLR(root->left); NLR(root->right); } } Caáu truùc Döõ lieäu - Caáu truùc caây
Duyệtcâynhịphântìmkiếm • Duyệt theo thứ tự giữa – (Left-Node-Right): Duyệt cây con bên trái, duyệt nút gốc, duyệt cây con bên phải voidLNR(TREE root) { if (root!=NULL) { LNR(root->left); cout<<root->data<<" "; LNR(root->right); } } Caáu truùc Döõ lieäu - Caáu truùc caây
Duyệtcâynhịphântìmkiếm • Duyệt theo thứ tự sau – (Left-Right-Node): Duyệt cây con bên trái, duyệt nút gốc, duyệt cây con bên phải voidLRN(TREE root) { if (root!=NULL) { LRN(root->left); LRN(root->right); cout<<root->data<<" "; } } Caáu truùc Döõ lieäu - Caáu truùc caây
Tìmmộtphầntửxtrongcây(đệquy) • Tìmmộtphầntửxtrongcây (đệquy): NODE* searchNode(TREE root, int X) { if(root!=NULL) { if(root->data == X) return root; if(root->data > X) returnsearchNode(root->left, X); returnsearchNode(root->right, X); } returnNULL; } Caáu truùc Döõ lieäu - Caáu truùc caây
Tìmmộtphầntửxtrongcây(khôngđệquy) • Tìmmộtphầntửxtrongcây (khôngđệquy): NODE * searchNode(TREE root, int 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; } returnNULL; } Caáu truùc Döõ lieäu - Caáu truùc caây