Cấu trúc Dữ liệu - Cấu trúc cây 23Cây nhị phân Duyệt cây nhị phâ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 NLR - Preorder Duyệt theo
Trang 1CHAPTER 7:
TREES
Trang 2Cấu trúc Dữ liệu - Cấu trúc cây 2
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 tốn, ứng dụng.
Giới thiệu cấu trúc dữ liệu cây nhị phân tìm kiếm
Trang 3Cấu trúc cây
Trang 4Cấu trúc Dữ liệu - Cấu trúc cây 4
Cấu trúc cây
Định nghĩa : cây 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 T1, T2 , , 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
Trang 5Cấu trúc Dữ liệu - Cấu trúc cây 5
Cấu trúc cây
Trang 6Cấu trúc Dữ liệu - Cấu trúc cây 6
Cấu trúc cây
Trang 7Cấu trúc Dữ liệu - Cấu trúc cây 7
Cấu trúc cây
Một số khái niệm cơ bả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
Trang 8Cấu trúc Dữ liệu - Cấu trúc cây 8
Cấu trúc cây
Một số khái niệm cơ bả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
Trang 9Cấu trúc Dữ liệu - Cấu trúc cây 9
Khái niệm
J
DR
B
LF
AK
nút gốc
Cạnh
Trang 10Cấu trúc Dữ liệu - Cấu trúc cây 10
Châu âu Mỹ Các nước
Trang 11Cấu trúc Dữ liệu - Cấu trúc cây 11
Giới thiệu Điểm Môi trường NN LT CT mẫu
Bài tập Thực hành Thi
Trang 12Cấu trúc Dữ liệu - Cấu trúc cây 12
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ĩ
Trang 13Cây nhị phân
Trang 14Cấu trúc Dữ liệu - Cấu trúc cây 14
Cây nhị phân
Định nghĩa : Cây : Cây nhị phân là cây mà mỗi nút
cĩ tối đa 2 cây con
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
Trang 15Cấu trúc Dữ liệu - Cấu trúc cây 15
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
Trang 16Cấu trúc Dữ liệu - Cấu trúc cây 16
Cây nhị phân
Figure 7.3: Binary tree structure
Trang 17Cấu trúc Dữ liệu - Cấu trúc cây 17
Cây nhị phân
Figure 7.4: Skewed trees
Trang 18Cấu trúc Dữ liệu - Cấu trúc cây 18
Cây nhị phân
Cây nhị phân dùng để biểu diễn một biểu thức tốn học :
Trang 19Cấu trúc Dữ liệu - Cấu trúc cây 19
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
Đườ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 đĩ.
i
2
Mức
Trang 20Cấu trúc Dữ liệu - Cấu trúc cây 20
Cây nhị phân
Biểu diễn cây nhị phân T
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ớ.
Trang 21Cấu trúc Dữ liệu - Cấu trúc cây 21
Cây nhị phân
Trang 22Cấu trúc Dữ liệu - Cấu trúc cây 22
Trang 23Cấu trúc Dữ liệu - Cấu trúc cây 23
Cây nhị phân
Duyệt cây nhị phâ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 NLR )- Preorder
Duyệt theo thứ tự giữa ( (LNR LNR )- Inorder
Duyệt theo thứ tựï sau ( (LRN LRN )- Postorder
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
Trang 24Cấu trúc Dữ liệu - Cấu trúc cây 24
Cây nhị phân
Duyệt theo thứ tự trước (Node-Left-Right)
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:
{
if (Root != NULL ) {
<Xử lý Root>;//Xử lý tương ứng theo nhu cầu
NLR (root->left);
NLR (root->right);
} }
Trang 25Cấu trúc Dữ liệu - Cấu trúc cây 25
Cây nhị phân
Duyệt theo thứ tự trước (Node-Left-Right)
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 :
Trang 26Cấu trúc Dữ liệu - Cấu trúc cây 26
A B
C F
L P
G M
AKết quả: B D H I N E J O K C F L P G M
Duyệt theo thứ tự trước (Node-Left-Right)
Trang 27Cấu trúc Dữ liệu - Cấu trúc cây 27
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);
} }
Trang 28Cấu trúc Dữ liệu - Cấu trúc cây 28
Duyệt theo thứ tự giữa (Left- Node-Right)
A B
C F
L P
G M
HKết quả: D N I B J O E K A F P L C M G
Trang 29Cấu trúc Dữ liệu - Cấu trúc cây 29
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
} }
Trang 30Cấu trúc Dữ liệu - Cấu trúc cây 30
Trang 31Cấu trúc Dữ liệu - Cấu trúc cây 31
Duyệt theo thứ tự sau (Left-Right-Node)
A B
C F
L P
G M
HKết quả: N I D O J K E B P L F M G C A
Trang 32Cấu trúc Dữ liệu - Cấu trúc cây 32
Cây nhị phân
Duyệt theo thứ tự sau (Left-Right-Node)
Tính tố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
Trang 33Cấu trúc Dữ liệu - Cấu trúc cây 33
Cây nhị phân
Biểu diễn cây tổng quát bằng cây nhị phâ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 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
Trang 34Cấu trúc Dữ liệu - Cấu trúc cây 34
Cây nhị phân
Biểu diễn cây tổng quát bằng cây nhị phâ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
Trang 35Cấu trúc Dữ liệu - Cấu trúc cây 35
Cây nhị phân
Biểu diễn cây tổng quát bằng cây nhị phân
Giả sử cĩ cây tổng quát như hình bên dưới :
A
Trang 36Cấu trúc Dữ liệu - Cấu trúc cây 36
Cây nhị phân
Biểu diễn cây tổng quát bằng cây nhị phân
Cây nhị phân tương ứng sẽ như sauA:
Trang 37Cấu trúc Dữ liệu - Cấu trúc cây 37
Cây nhị phân
Một cách biểu diễn cây nhị phân khác
Đơ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 tagTNode
{
struct tagTNode * pParent;
struct tagTNode * pLeft;
struct tagTNode * pRight;
} TNODE ;
typedef TNODE * TREE ;
Trang 38Cấu trúc Dữ liệu - Cấu trúc cây 38
Cây nhị phân
Một cách biểu diễn cây nhị phân khác
Trang 39Cây nhị phân tìm kiếm
(Binary search tree)
Trang 40Cấu trúc Dữ liệu - Cấu trúc cây 40
Cây nhị phân tìm kiếm (BST)
Định nghĩa : cây : cây nhị phân tìm kiếm ( BST ) 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ếu số nút trên cây là N thì chi phí tìm kiếm trung bình chỉ khoảng log2N
Trang 41Cấu trúc Dữ liệu - Cấu trúc cây 41
Cây nhị phân tìm kiếm
44
Trang 42Cấu trúc Dữ liệu - Cấu trúc cây 42
Trang 43Cấu trúc Dữ liệu - Cấu trúc cây 43
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
Trang 44Cấu trúc Dữ liệu - Cấu trúc cây 44
Trang 45Cấu trúc Dữ liệu - Cấu trúc cây 45
Thêm một nút vào cây BST
int
int InsertTree InsertTree (tree &root , int x) {
if (root != NULL) {
Trang 46Cấu trúc Dữ liệu - Cấu trúc cây 46
Trang 47Cấu trúc Dữ liệu - Cấu trúc cây 47
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
void CreateTree CreateTree (tree &root) {
int x,n;
cout <<“Nhap n = “; cin>>n;
for (int ( int i=1; i<=n;i++) {
cout <<“Nhap gia tri:”; cin <<“Nhap gia tri:”; cin>>x;
InsertTree (root,x);
} }
Trang 48Cấu trúc Dữ liệu - Cấu trúc cây 48
Tạo cây nhị phân tìm kiếm
25 10
37 29
35 32
50 41
25 37 10 18 29 50 3 1 6 5 12 20 35 13 32 41
Trang 49Cấu trúc Dữ liệu - Cấu trúc cây 49
Duyệt cây nhị phân tìm kiếm
Thao tác duyệt cây trên cây nhị phân tìm kiếm hồn tồ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
Trang 50Cấu trúc Dữ liệu - Cấu trúc cây 50
Duyệt cây nhị phân tìm kiế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
void NLR NLR (TREE root)
{
if (root!=NULL) {
cout <<root->data<<" ";
NLR (root->left);
NLR (root->right);
} }
Trang 51Cấu trúc Dữ liệu - Cấu trúc cây 51
Duyệt cây nhị phân tìm kiế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
void LNR LNR (TREE root)
{
if (root!=NULL) {
LNR (root->left);
cout <<root->data<<" ";
LNR (root->right);
} }
Trang 52Cấu trúc Dữ liệu - Cấu trúc cây 52
Duyệt cây nhị phân tìm kiế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
void LRN LRN (TREE root)
{
if (root!=NULL) {
LRN (root->left);
LRN (root->right);
cout <<root->data<<" ";
} }
Trang 53Cấu trúc Dữ liệu - Cấu trúc cây 53
Tìm một phần tử x trong cây
(đệ quy)
Tìm một phần tử x trong cây (đệ quy):
NODE * searchNode ( TREE root, int X) {
if (root!=NULL) {
if (root->data == X)
return root;
if (root->data > X)
return searchNode (root->left, X);
return searchNode (root->right, X);
}
return NULL ; }
Trang 54Cấu trúc Dữ liệu - Cấu trúc cây 54
Tìm một phần tử x trong cây
(khơng đệ quy)
Tìm một phần tử x trong cây (khơng đệ quy):
NODE * searchNode * searchNode (TREE ( TREE root, int root, int x) {
Trang 55Cấu trúc Dữ liệu - Cấu trúc cây 55
Tìm một phần tử x=13 trong cây
25 10
37 29
35 32
50 41
Tìm kiếm 13
Khác nhau Giống nhau Node gốc nhỏ hơn Node gốc lớn hơn
Tìm thấy Số node duyệt: 5Số lần so sánh: 9
Trang 56Cấu trúc Dữ liệu - Cấu trúc cây 56
25 10
37 29
35 32
50 41
Tìm kiếm 13
Khác nhau Giống nhau Node gốc nhỏ hơn Node gốc lớn hơn
Tìm thấy Số node duyệt: 5Số lần so sánh: 9
Tìm một phần tử x=13 trong cây
Trang 57Cấu trúc Dữ liệu - Cấu trúc cây 57
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(log2n)
Trang 58Cấu trúc Dữ liệu - Cấu trúc cây 58
Trang 59Cấu trúc Dữ liệu - Cấu trúc cây 59
Tìm một phần tử x trong cây
Trang 60Cấu trúc Dữ liệu - Cấu trúc cây 60
Thêm một phần tử x vào cây
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 ngồ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:
Trang 61Cấu trúc Dữ liệu - Cấu trúc cây 61
Thêm một phần tử x vào cây
root->data = X;
root->left = root->right = NULL;
}
Trang 62Cấu trúc Dữ liệu - Cấu trúc cây 62
Thêm một phần tử x vào cây
Trang 63Cấu trúc Dữ liệu - Cấu trúc cây 63
Trang 64Cấu trúc Dữ liệu - Cấu trúc cây 64
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
Trang 65Cấu trúc Dữ liệu - Cấu trúc cây 65
Trang 66Cấu trúc Dữ liệu - Cấu trúc cây 66
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)
1 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
Trang 67Cấu trúc Dữ liệu - Cấu trúc cây 67
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)
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ĩ
Trang 68Cấu trúc Dữ liệu - Cấu trúc cây 68
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)
Hủy một phần tử cĩ khĩa x
Trường hợp 3: X cĩ đủ 2 con
Trang 69Cấu trúc Dữ liệu - Cấu trúc cây 69
Hủy một phần tử cĩ khĩa x
Trường hợp 3: X cĩ đủ 2 con
Trường hợp cuối cùng:
Phần tử này cĩ tối đa một con
hợp đầu
vẫn là CNPTK
Trang 70Cấu trúc Dữ liệu - Cấu trúc cây 70
Hủy một phần tử cĩ khĩa x
Trường hợp 3: X cĩ đủ 2 con
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 :
Việc chọn lựa phần tử nào là phần tử thế mạng hồn tồ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.
Trang 71Cấu trúc Dữ liệu - Cấu trúc cây 71
Trang 72Cấu trúc Dữ liệu - Cấu trúc cây 72
Hủy một phần tử cĩ khĩa x
Trường hợp 3: X cĩ đủ 2 con
cơng hoặc khơng cĩ X trong cây :
cho nút p
Trang 73Cấu trúc Dữ liệu - Cấu trúc cây 73
Hủy một phần tử cĩ khĩa x
{
if (root== NULL ) return 0;
if (root->data > X) return delNode (root->left, X);
if (root->data < X) return delNode (root->right, X);
Trang 74Cấu trúc Dữ liệu - Cấu trúc cây 74
Trang 75Cấu trúc Dữ liệu - Cấu trúc cây 75
Hủy tồn bộ cây nhị phân tìm kiếm
Việc tồ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
Trang 76Cấu trúc Dữ liệu - Cấu trúc cây 76
Cây nhị phân tìm kiếm
Nhận xét:
cây
đương tìm kiếm nhị phân trên mảng cĩ thứ tự
O(n)