Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 30 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
30
Dung lượng
2,62 MB
Nội dung
CẤU TRÚC DỮ LIỆU & GIẢI THUẬT CÂY (TREE) Tree • Cây tập hữu hạn node có kiểu liệu, có node đặc biệt gọi node gốc (root) • Giữa node có quan hệ phân cấp gọi “quan hệ cha con” Định nghĩa dạng đệ quy: • Một node cây, node gốc (root) • Cây gồm node kết hợp với số bên Tree • Cây rỗng: Cây khơng có node • Các node gọi có đường node • Mỗi node (trừ node gốc) có node nằm nó, gọi node cha • Node con: Các node nằm node • Node lá: Các node khơng có • Mức node: node gốc có mức Nếu node cha có mức i node có mức i+1 • Chiều cao (sâu) cây: Số mức lớn node có Tree • Độ sâu node: Độ dài đường node gốc node Một node mức i có độ dài i • Bậc node: Số node Node có bậc = gọi node • Bậc cây: Bậc lớn node Cây có bậc n gọi n-phân • Node nhánh: Node có bậc khác khơng phải node gốc • Các node có cha gọi anh em • Tập riêng biệt gọi rừng • Một gọi có thứ tự node node bố trí theo thứ tự đó, ngược lại gọi khơng có thứ tự Tree root Mức Mức Node cha Mức Mức Node Node Node Mức Ví dụ: Cây mục lục sách Sách C1 1.1 C2 1.2 2.1 2.3 C3 2.2 3.1 3.2 3.1.1 3.1.2 3.1.3 Cây nhị phân • Cây nhị phân rỗng mà node có tối đa node Biểu diễn nhị phân • Sử dụng danh sách liên kết struct node { int data; node *left, *right; }; typedef node * Pnode; • Để khai báo biến cho cây, khai báo biến trỏ cho trỏ vào phần tử gốc Ví dụ: Pnode tree; Một số thao tác nhị phân • Khởi tạo rỗng tree = NULL; • Duyệt Duyệt tiền tự (NLR): duyệt nút gốc, duyệt tiền tự trái duyệt tiền tự phải Duyệt trung tự (LNR): duyệt trung tự trái, duyệt nút gốc, duyệt trung tự phải Duyệt hậu tự (LRN): duyệt hậu tự trái, duyệt hậu tự phải, sau duyệt nút gốc Duyệt tiền tự • Nếu rỗng => khơng làm • Nếu khác rỗng: Thăm node gốc Duyệt bên trái Duyệt bên phải • Hàm: void duyet_NLR (Pnode tree) { if (tree!=NULL) { ; duyet_NLR(tree->left); duyet_NLR(tree->right); } } 10 Cây nhị phân tìm kiếm • Cây nhị phân tìm kiếm (Binay Search Tree) nhị phân mà node: Phần tử node lớn phần tử bên trái Nhỏ phần tử bên phải • Cài đặt nhị phân tìm kiếm: Sử dụng danh sách liên kết struct node { int data; node *left, *right; }; typedef node * Pnode; 16 Tìm kiếm node NPTK • Để tìm kiếm node có giá trị x NPTK, so sánh giá trị node gốc với x: Nếu node gốc = NULL khơng có x Ngược lại, x giá trị node gốc dừng, tìm node chứa x Nếu x > giá trị node gốc tìm x bên phải Nếu x < giá trị node gốc tìm x bên trái 17 Tìm kiếm node NPTK Pnode search (Pnode tree,int x) { if(tree==NULL) return NULL; if(tree->data==x) return tree; if(xdata) search(tree->left,x); else search(tree->right,x); } 18 Ví dụ Tìm node có giá trị 32 hình bên • So sánh 32 với node gốc 20, 32>20 tìm tiếp bên phải có node gốc 35 • So sánh 32 với node gốc 35, 32 node gốc thêm x bên phải 20 Thêm node vào NPTK void insert (Pnode &tree, int x) { if(tree==NULL) { tree=new node; tree->data=x; tree->left=tree->right=NULL; return; } if(x==tree->data) return; else if(x < tree->data) insert (tree->left,x); else insert (tree->right,x); } 21 Ví dụ Thêm node có giá trị 33 vào • So sánh 33 với node gốc 20, 33>20 xét tiếp bên phải có node gốc 35 • So sánh 33 với node gốc 35, 3332 xét tiếp bên phải Vì node bên phải = NULL, thêm node chứa 33 vào bên phải node chứa giá trị 32 20 15 10 35 18 13 32 44 27 22 Xóa phần tử x NPTK • Khi xóa node, cần phải điều chỉnh lại để nhị phân tìm kiếm • Các trường hợp xóa: • Xóa node có giá trị 35 node 20 15 20 35 15 NULL 23 Xóa phần tử x NPTK • Xóa node có giá trị 15 node trung gian có node 20 20 15 35 18 35 18 • Xóa node có giá trị 20 node trung gian có node 20 32 15 18 35 32 15 44 18 35 44 24 Thuật tốn xóa node • Nếu khơng tìm thấy node chứa giá trị x dừng • Nếu gặp node p chứa x: TH1: Nếu p node hủy node p TH2: Nếu p có node cho tree đến node con, hủy p TH3: Nếu p có đủ node con, tìm node nhỏ bên phải (hoặc node lớn bên trái), thay giá trị node p giá trị node nhỏ bên phải, sau xóa node nhỏ 25 Xóa phần tử x NPTK void deletenode (Pnode &tree,int x) { Pnode p,f; p=tree; if(tree==NULL) return; if(x < tree->data) deletenode(tree->left,x); else if(x > tree->data) deletenode(tree->right,x); else if(tree->left==NULL && tree->right ==NULL) { delete tree; tree=NULL; } else if(tree->left==NULL) { tree=tree->right; delete p; } else if(tree->right==NULL) { tree=tree->left; delete p; } else { p=min(tree->right); f=parent(tree,p); tree->data=p->data; if(f!=NULL) { if(f->left==p) f->left=NULL; else if(f->right==p) f->right=p->right; delete p; } } } 26 Xóa phần tử x NPTK Pnode (Pnode tree) { if(tree->left==NULL) return tree; return min(tree->left); } Pnode parent (Pnode tree, Pnode p) { if(tree==NULL || tree==p) return NULL; if(tree->left==p||tree->right==p) return tree; if(p->data > tree->data) return parent(tree->right,p); else return parent(tree->left,p); } 27 Bài tập Viết chương trình thực thao tác nhị phân tìm kiếm: a b c d e f g h i Thêm phần tử Tìm kiếm phần tử Hủy bỏ phần tử Duyệt theo NLR, LNR, LRN Đếm số node Tính chiều cao Đếm số node có: bậc 1, bậc Tìm node bên trái, bên phải node Tính tổng phần tử 28 Bài tập Hãy vẽ nhị phân tìm kiếm cho giá trị sau: paper, hero, talent, green, paint, time, potato, hello, tomato, talkative, empty, storage Q Hãy vẽ nhị phân tìm kiếm cho dãy số: 40, 25, 74, 57, 65, 80, 16, 20, 43, 22, 36, 78 Cho biết thứ tự duyệt LNR, NLR, LRN, RNL, NRL, RLN hình bên: A P D M H E T N K C 29 Bài tập Một sinh viên có thông tin: mã số, họ tên, năm sinh, điểm trung bình Viết chương trình tạo nhị phân tìm kiếm kiểu sinh viên, sinh viên nhập làm node gốc, dựa vào mã số sinh viên để lưu vào bên trái bên phải nhị phân tìm kiếm, viết số thao tác sau: a b c d e Thêm sinh viên Tìm kiếm sinh viên theo mã số Hủy bỏ sinh viên theo mã số Xuất danh sách sinh viên Đếm số sinh viên có điểm trung bình >=5 30