Bài giảng Cấu trúc dữ liệu và giải thuật - Chương 5: Cây nhị phân tìm kiếm cung cấp cho người học các kiến thức: Khái niệm, đặc điểm, định nghĩa cấu trúc dữ liệu, các lưu ý khi cài đặt, các thao tác xử lý. Mời các bạn cùng tham khảo nội dung chi tiết.
Trang 1Chương 5 Cây nhị phân
Trang 2Nội dung
1 Khái niệm
2 Đặc điểm
3 Định nghĩa cấu trúc dữ liệu
4 Các lưu ý khi cài đặt
5 Các thao tác xử lý
2
Trang 3Khái niệm
Bậc của một nút: là số cây con của nút đó
Bậc của cây: là bậc lớn nhất của các nút trong 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
11
0
0
0
0
Trang 4kể từ gốc đến x
Chiều cao h của cây: Mức lớn nhất của các nút lá
4
x
Trang 5Đặc điểm của cây nhị phân
Trang 6Biểu diễn cây nhị phân
Cây nhị phân là một cấu trúc bao gồm các phần tử (node) được kết nối với nhau theo quan hệ “cha-con” với mỗi cha có tối đa 2 con
Mỗi nút gồm các thông tin:
Dữ liệu lưu trữ: data
Liên kết tới cây con trái của nút: pLeft
Liên kết tới cây con phải của nút: pRight
6
Trang 7Định nghĩa kiểu dữ liệu dùng C
Trang 8Ví dụ khai báo node chứa giá trị nguyên
typedef struct TNode
Trang 9Cây nhị phân tìm kiếm
Là 1 cây nhị phân
Giá trị của một node luôn lớn hơn giá trị của các node nhánh trái và nhỏ hơn giá trị các node
nhánh phải
Nút có giá trị nhỏ nhất nằm ở nút trái nhất của cây
Nút có giá trị lớn nhất nằm ở nút phải nhất của cây 9
7
23 4
Trang 10Các lưu ý khi cài đặt
Bước 1: Khai báo kiểu dữ liệu biểu diễn cây
Bước 2: Xây dựng hàm đưa dữ liệu (nhập) vào cây
Bước 3: Xây dựng các thao tác duyệt, tìm kiếm, huỷ, …
10
Trang 11Cấu trúc chương trình
11
Khai báo cấu trúc cây Khởi tạo cây rỗng Xây dựng cây Các thao tác Hủy cây
Trang 13nhỏ hơn node đang xét thì thêm về bên trái
Ngược lại thì thêm về
bên phải
Trang 14Hàm thêm một phần tử vào cây
Trang 15Bài tập
1 Viết hàm tạo cây nhị phân số nguyên từ các
giá trị nhập vào từ bàn phím Quá trình nhập cho đến khi gặp giá trị trùng hoặc hết
bộ nhớ
2 Viết hàm tạo cây nhị phân số nguyên từ
dãy số nguyên cho trước
15
Trang 17Bước Kết quả duyệt theo thứ tự NLR
Trang 18 Duyệt cây con bên
phải của t theo thứ tự
NLR
18
void NLR (Tree t) {
if(t!=NULL) {
cout<<t->Key<<“\t”; NLR(t->pLeft);
NLR(t->pRight);
} }
Trang 1919
Trang 20Bước Kết quả duyệt theo thứ tự LNR
Trang 21 Duyệt cây con bên
phải của t theo thứ tự
LNR
21
void LNR (Tree t) {
if(t!=NULL) {
LNR(t->pLeft);
cout<<t->Key<<“ “; LNR(t->pRight);
} }
Trang 23if(t!=NULL) {
LRN(t->pLeft);
LRN(t->pRight);
cout<<t->Key<<“ “; }
}
Trang 24Bài tập
Vẽ cây nhị phân tìm kiếm theo thứ tự nhập:
27, 19, 10, 21, 3, 15, 41, 50, 30, 7
Hãy duyệt cây trên theo thứ tự giữa
Vẽ cây nhị phân tìm kiếm theo thứ tự nhập:
H, B, C, A, E, D, T, M, X, O
Hãy duyệt cây trên theo thứ tự sau
24
Trang 25Kiểm tra kết quả duyệt bằng cách xây dựng lại cây nhị phân từ kết quả duyệt
Tạo cây từ kết quả duyệt NLR
Chọn giá trị đầu tiên làm node gốc
Lần lượt đưa các giá trị còn lại từ trái sang phải vào cây theo nguyên tắc tạo cây
Tạo cây từ kết quả duyệt LRN
Chọn giá trị cuối cùng làm node gốc
Lần lượt đưa các giá trị còn lại từ phải sang trái vào cây theo nguyên tắc tạo cây
25
Trang 26Bài tập
Vẽ cây nhị phân tìm kiếm T biết rằng khi duyệt cây T theo thứ tự NLR thì được dãy sau: 9, 4, 1, 3, 8, 6, 5, 7, 10, 14, 12, 13, 16, 19
Hãy duyệt cây T trên theo thứ tự LRN
Liệt kê các nút lá của cây Liệt kê các nút nhánh của cây
26
Trang 27Vẽ cây nhị phân tìm kiếm T biết rằng khi duyệt cây T theo thứ tự LRN thì được dãy sau: 1, 4, 7, 5, 3, 16, 18, 15, 29, 25, 30, 20, 8
Hãy duyệt cây T trên theo thứ tự NLR
Cây T có chiều cao là bao nhiêu? Tìm các đường đi từ gốc có độ dài là 4 trên cây
27
Bài tập
Trang 31Bài tập
Cho cây nhị phân tìm kiếm, mỗi node có giá trị nguyên, hãy định nghĩa các hàm sau:
1 In ra các node có giá trị chẵn
2 In ra các node có giá trị lớn hơn x
3 Đếm số node của cây
4 Tính độ cao của cây
31
Trang 32Bài tập
5 Đếm số node lá (node bậc 0)
6 Đếm số node có 1 cây con (node bậc 1)
7 Đếm số node chỉ có 1 cây con phải
8 Đếm số node có 1 cây con trái
9 Đếm số node 2 cây con (node bậc 2)
10 In các node trên từng mức của cây
11 Cho biết độ dài đường đi từ gốc đến node x
32
Trang 33Xóa node trên cây
1 Node lá
2 Node có 1 cây con
3 Node có 2 cây con
Trang 34Xóa node lá
Xóa 1 Xóa 23
Trang 35Xóa node 1 cây con
Node cha
của 6
Trang 36Xóa node 1 cây con
6
Trang 37Xóa node có 2 cây con
nhất của cây con trái
Bước 2: Thay giá trị của
node thế mạng vào node cần xóa
Bước 3: Xóa node thế mạng
Trang 38Xóa node 2 cây con
16
Node thế mạng
Trang 39Xóa node 2 cây con
Xóa 36
Bước 2: Thay giá trị node thế
mạng cho node cần xóa
16
Cập nhật giá trị
Node thế mạng
Trang 40Xóa node 2 cây con
16
Xóa
Trang 41Xóa node 2 cây con
Trang 42Cho dãy số theo thứ tự nhập từ trái sang phải: 20, 15, 35, 30,
11, 13, 17, 36, 47, 16, 38, 28, 14
Vẽ cây nhị phân tìm kiếm cho dãy số trên
Trình bày từng bước và vẽ lại cây sau khi lần lượt xoá các
nút: 11 và 35
42
Bài tập
Trang 43 Viết hàm xóa node có giá trị x trong cây nhị phân số nguyên
43
Trang 44void Remove( Tree & t , int x )
}
Trang 46 Trường hợp xấu nhất, cây có thể bị suy biến thành 1 DSLK 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à log2(n)
46
Trang 47Cây nhị phân tìm kiếm cân bằng
Phát minh: Nhà toán học Nga G M Adel’Son-Vel’Skil
và E M Landis (1962)
Cấu trúc cây giúp tối ưu thời gian tìm kiếm
Cây nhị phân tìm kiếm cân bằng: cây AVL
Chi phí tìm kiếm, thêm mới, xoá trong cây n nút là O(log n)
47
Trang 48Định nghĩa
Cây AVL là một cây nhị phân tìm kiếm
Chiều cao cây con trái và phải của nút gốc hơn kém nhau không quá 1
Cả hai cây con trái và phải cũng phải là cây AVL
48
Trang 49Chỉ số cân bằng (Balance factor)
Chỉ số cân bằng (bF – balance Factor) của một nút:
bF = hR – hL
hL: chiều cao cây con trái
hR: chiều cao cây con phải
Có 3 trường hợp:
bF = 0: hL = hR (Ký hiệu EH: Equal Height)
bF > 0: hL < hR (Ký hiệu RH: Right Higher)
bF < 0: hL > hR (Ký hiệu LH: Left Higher)
49
Trang 50Khai báo cấu trúc cây AVL
typedef struct AVLNode
Trang 51Trường hợp 1: Lệch trái
51
Trang 52Trường hợp 2: Lệch phải
52
Trang 53Trường hợp 1.1: T1 lệch trái
53
Quay đơn Left - Left
Trang 54Trường hợp 1.2: T1 không lệch
54
Quay đơn Left - Left
Trang 55void RotateLL ( AVLTree &T)
{
AVLNode * T1 = T-> pLeft ; T->pLeft = T1->pRight ;
T1-> pRight = T;
switch (T1-> bF)
{
case LH: T-> bF = EH; T1-> bF = EH; break ;
case EH: T-> bF = LH; T1-> bF = RH; break ;
}
T = T1;
}
Trang 56Trường hợp 1.3: T1 lệch phải
56
Quay kép Left - Right
Trang 57void RotateLR(AVLTree &T)
{
AVLNode * T1 = T-> pLeft ; AVLNode * T2 = T1-> pRight ; T-> pLeft = T2-> pRight ; T2-> pRight = T;
case EH: T-> bF = EH; T1-> bF = EH; break ;
case RH: T-> bF = EH; T1-> bF = LH; break ;
}
T2-> bF = EH;
T = T2;
}
Trang 60Thêm 1 node vào cây AVL
Tương tự như trên cây NPTK
Sau khi thêm xong, nếu chiều cao của cây thay đổi Nếu
có mất cân bằng cân bằng lại ở nút này
Trang 61int InsertNode(AVLTree &T, int X)
case EH: T->bF = LH; return 2;
case LH: BalanceLeft(T); return 1;
}
}
Trang 63T->pLeft = T->pRight = NULL;
return 2; //Thêm thành công và chiều cao tăng
}
Trang 64int BalanceLeft(AVLTree &T)
return 0;
}
Trang 65Hủy 1 node trên cây
Tương tự như trên cây NPTK
Sau khi hủy, nếu mất cân bằng cân bằng lại
Hàm deleteNode trả về giá trị
1: hủy thành công
0: không có X trong cây
2: hủy thành công và chiều cao của cây giảm
65
Trang 66int DeleteNode(AVLTree &T, int X)
case EH: T-> bF = RH;
return 1;
case BalanceRight (T); }
}