Binary Tree Phần data: chứa giá trị, thông tin… Liên kết đến nút con trái nếu có Liên kết đến nút con phải nếu có Có duy nhất 1 đường đi từ gốc đến 1 nút... Xác định độ sâu/chiề
Trang 1Tree Structure
Trang 2Nội dung
Cây Top-Down
B-Tree
Trang 3Cấu trúc dữ liệu
Trang 4Cấu trúc cây
Nhị phân: mỗi nút có {0,1, 2} nút con
Tam phân: mỗi nút có {0,1,2,3} nút con
Trang 5Cấu trúc cây
Sao trong máy tính, cây lại thể hiện ngược?
Trang 6Khái niệm
J
D R
B
L F
A K
nútgốc
Cạnh
Trang 7Khái niệm
Nút gốc: không có nút cha
Nút lá: không có nút con
Nút trong: không phải nút con và nút gốc
Chiều cao: khoảng cách từ gốc đến lá
Nút gốc
Trang 8Khái niệm
Root Node A
Node H
Node B
Node G Node F
Node E Node D
Node C
Node K Node J
Node I
Trang 9Nội dung
Trang 10Binary Tree
Phần data: chứa giá trị, thông tin…
Liên kết đến nút con trái (nếu có)
Liên kết đến nút con phải (nếu có)
Có duy nhất 1 đường đi từ gốc đến 1 nút
Trang 12Binary Tree
Nút gốc và nút trung gian có đúng 2 con
cây 2n-1
A
Trang 13Binary Tree
Phải là cây nhị phân đúng
Trang 14Binary Tree
Do cây là cấu trúc ko tuyến tính
3 cách duyệt cây NP
Duyệt theo thứ tự trước PreOrder: NLR
Duyệt theo thứ tự giữa InOrder: LNR
Duyệt theo thứ tự sau PostOrder: LRN
Trang 16Binary Tree
typedef struct node
{
DataType info;
struct node * left;
struct node * right;
} NODE;
Cấu trúc của một nút
Chứa thông tin của nút
Trỏ đến nút con trái Trỏ đến nút con phải
Trang 20Binary Tree
int InsertLeft(NodePtr p, int x)
{
if (p == NULL) return FALSE;
if (p->left != NULL) return FALSE;
p->left = CreateNode(x);
return TRUE;
}
Trang 21Binary Tree
int InsertRight(NodePtr p, int x)
{
if (p == NULL) return FALSE;
if (p->right != NULL) return FALSE;
p->right = CreateNode(x);
return TRUE;
}
Trang 23Binary Tree
void PreOrder(NodePtr pTree)
{
if (pTree != NULL) {
printf(“%d ”, pTree->info);
PreOrder(pTree->left);
PreOrder(pTree->right);
} }
Trang 24printf(“%d ”, pTree->info);
InOrder(pTree->right);
}
Trang 25PostOrder(pTree->right);
printf(“%d ”, pTree->info);
} }
Trang 26if (pTree == NULL) return NULL;
if (pTree->info == x) return pTree;
p = Search(pTree->left, x);
if (p == NULL)
p = Search(pTree->right, x);
Trang 27ClearTree(pTree->right);
FreeNode(pTree);
Trang 28 Xác định độ sâu/chiều cao của cây
Tìm giá trị nhỏ nhất/lớn nhất trên cây
Tính tổng các giá trị trên cây
Đếm số nút có giá trị bằng x
Trang 29Nội dung
Trang 30Binary Search Tree
Giá trị của tất cả nút con trái < nút gốc
Giá trị của tất cả nút con phải > nút gốc
5
< 5 > 5
Trang 31Binary Search Tree
10
30
2 45
Trang 32Binary Search Tree
8<9
9=9
Trang 33Binary Search Tree
Trang 34Binary Search Tree
Trang 35Binary Search Tree
Dựa trên chiều cao của cây
Trang 36Binary Search Tree
Xuất phát từ gốc
Nếu nút = NULL => ko tìm thấy
Nếu khoá x = khóa nút gốc => tìm thấy
Ngược lại nếu khoá x < khoá nút gốc => Tìm trên cây bên trái
Ngược lại => tìm trên cây bên phải
Trang 37Binary Search Tree
p = Search(node->right, x);
Trang 38Binary Search Tree
Chèn
Xóa
Giá trị nhỏ hơn ở bên cây con trái
Giá trị lớn hơn ở bên cây con phải
Trang 39Binary Search Tree
Thực hiện tìm kiếm giá trị x
Tìm đến cuối nút Y (nếu x ko
tồn tại trong cây)
Nếu x < y, thêm nút lá x bên trái
Trang 40Binary Search Tree
void Insert(NodePtr pTree, int x) {
if (pTree->right == NULL) {
node = CreateNode(x); pTree->right = node;
Trang 41Binary Search Tree
Thực hiện tìm nút có giá trị x
Nếu nút là nút lá, delete nút
Ngược lại
Thay thế nút bằng một trong hai nút sau
Y là nút lớn nhất của cây con bên trái
Z là nút nhỏ nhất của cây con bên phải
Chọn nút Y hoặc Z để thế chỗ
Giải phóng nút
Trang 42Binary Search Tree
Trang 43Binary Tree Search
của p trỏ tới nút con duy nhất của nó, rồi hủy p
Trang 44Binary Search Tree
thay thế theo 1 trong 2 cách như sau
Nút lớn nhất trong cây con bên trái
Nút nhỏ nhất trong cây con bên phải
Nút lớn Nút nhỏ
Trang 45Binary Search Tree
Trang 46Binary Search Tree
Trang 47Binary Search Tree
Minh họa xóa (25)
Trang 48Binary Search Tree
Minh họa xóa (25)
Trang 49Binary Search Tree
Minh họa xóa (25)
Trang 50Binary Search Tree
Minh họa xóa (25)
Trang 51Binary Search Tree
Minh họa xóa (25)
Trang 52Binary Search Tree
52
Trang 53Binary Search Tree
- Đưa giá trị của nút rp lên nút p
52
Trang 54Binary Search Tree
- Chuyển liên kết phải của p đến liên kết phải của rp
52
Trang 55Binary Search Tree
- Xoá nút rp
52
Trang 56Binary Search Tree
- Sau khi xoá
52
Trang 57Binary Search Tree
Remove (NodePtr &T, int x)
Nếu T = NULL ⇒ thoát
Nếu T->info > x ⇒ Remove(T->left, x)
Nếu T->info <x ⇒ Remove(T->right, x)
Nếu T->info = x
P = T
Nếu T có 1 nút con thì T trỏ đến nút con đó
Ngược lại có 2 con
Gọi f = p và rp = p->right;
Tìm nút rp sao cho rp->left = null và nút f là nút cha nút rp
Thay đổi giá trị nội dung của T và rp
Nếu f = p (trường hợp đặc biệt) thì: f->right = rp->right;
Trang 58Binary Search Tree
int Remove(NodePtr &T, int x){
if ( T == NULL)
return FALSE; // không tìm thấy nút cần xoá
if (T->info >x) // tìm bên trái
Trang 59Binary Search Tree
else { // trường hợp có 2 con chọn nút nhỏ nhất bên con phải
f = p; // f để lưu cha của rp
rp = p->right; // rp bắt đầu từ p->right
while ( rp->left != NULL) {
f = rp; // lưu cha của rp
rp = rp->left; // rp qua bên trái
p->info = rp->info; // đổi giá trị của p và rp
if ( f == p) // nếu cha của rp là p
f->right = rp->right;
else // f != p
f->left = rp->right;
p = rp; // p trỏ đến phần tử thế mạng rp
Trang 60Binary Search Tree
Bài tập
Cài đặt cấu trúc dữ liệu liên kết cho cây nhị phân tìm kiếm
Cài đặt các thao tác xây dựng cây: NewNode, Init, IsEmpty, CreateNode
Cài đặt thao tác cập nhật: Insert, Remove, ClearTree
Xuất danh sách tăng dần và giảm dần
Kiểm tra xem cây có phải là cây nhị phân đúng
Kiểm tra xem cây có phải là cây nhị phân đầy đủ
Xác định nút cha của nút chứa khoá x
Đếm số nút lá, nút giữa, kích thước của cây
Xác định độ sâu/chiều cao của cây
Trang 61Mở rộng BST
thường làm cây mất cân bằng
Xoay trái RotateLeft
Xoay phải RotateRight
Trang 69Mở rộng BST
Thủ tục RotateLeft xoay nút root qua trái và trả về địa chỉ của nút gốc mới (thay cho root)
NodePtr RotateLeft(NodePtr root)
Nếu pRoot khác rỗng & có cây con phải
p = root->rightroot->right = p->leftp->left = root
return p
Trang 70 Lưu ý: phải cập nhật link từ nút cha đến nút gốc mới
Ví dụ xoay nút p, trong đó p trỏ đến nút con trái của f
Trang 73Mở rộng BST
Thủ tục RotateRight xoay nút root qua phải và trả về địa chỉ của nút gốc mới (thay cho root)
NodePtr RotateRight(NodePtr root)
Nếu pRoot khác rỗng & có cây con trái
p = root->leftroot->left = p->rightp->right = root
return p
Trang 75Nội dung
Trang 78Cây NP hoàn toàn cân bằng
Trang 79Cây NP hoàn toàn cân bằng
Trang 80Cây NP hoàn toàn cân bằng
4
1 (T1)
Trang 81Cây NP hoàn toàn cân bằng
Tối ưu nhất cho thao tác trên cây
Tốc độ tìm kiếm tỉ lệ với O(logn) với n là số nút
Thường bị mất cân bằng
Do thêm hay xoá
Chi phí để cân bằng rất lớn do thao tác trên toàn bộ cây
bằng!
Trang 82Cây AVL
Do tác giả Adelson-Velskii và Landis khám phá
Cây nhị phân cân bằng đầu tiên
Là cây nhị phân tìm kiếm
Độ cao của cây con trái và cây con phải chênh lệch
ko quá 1
Các cây con cũng là AVL
Trang 83Cây AVL
hl(p) là chiều cao của cây con trái nút p
hr(p) là chiều cao của cây con phải của p
Các trường hợp có thể xảy ra trên cây AVL
Trang 8415 27
35 54
30
30 25
35 54
(T1)
(T2)
Trang 8515 27
35
(T1)
30 25
35 54 27
(T3)
20
30 25
35 54 27
Trang 86Cây AVL
P
TR TL
30 25
35 54 27
(T2)
40 30
Trang 87Cây AVL
Hiệu số chiều cao cây con trái với cây con phải
Xét một nút p bất kỳ trong cây AVL thì bf
bf(p) = 0: hl(p) = hr(p)
bf(p) = 1: hl(p) = hr(p) + 1
bf(p) = -1: hr(p) = hl(p) +1
Trang 88Cây AVL
Minh họa chỉ số
0
1 0
0
-1 -1
0 0
(T4)
0 0 0
(T1) (T2)
(T3)
-1 0
-1 1
-1 -1
(T5)
0 1 0
-1 0
0 0
Độ cao của cây rỗng là -1
Trang 89Cây AVL
Thêm một nút vào giống như thêm vào cây NPTK
Tính lại chỉ số cân bằng của các nút có ảnh hưởng
Sau đó xét cây có bị mất cân bằng ko, nếu có thì phải cân bằng lại cây
Cân bằng các nút theo các phép xoay thích hợp!
Trang 90Cây AVL
Sau khi thêm vào thì nút mới là nút lá
Có thể mất cân bằng ?
Trường hợp nào ko ?
Lệch trái: cây sẽ mất cân bằng nếu nút thêm vào là
vị trí sau bên trái của một nút trước gần nhất đang
bị lệnh trái
Trang 94r p
h = n+1
Trang 97T2-1 h=n-1
T2-2 h=n-1
Trang 98T2-2 h=n-1
2
Trang 99Cây AVL
-1 0
0
q
T2-1 h=n-1
T2-2 h=n-1
Trang 100Cây AVL
Khi thêm vào cây nếu cây bị mất cân bằng
Thực hiện cân bằng lại, có 2 trường hợp
Có thể chỉ dùng 1 phép xoay
Dùng 2 phép xoay như trường hợp 2
Trường hợp cây lệch về bên phải thì tương tự (đối xứng)
Trang 101Cây AVL
Bổ sung thêm trường bf cho cấu trúc cây BST
typedef struct node
{
DataType info;
int bf;
struct node * left;
struct node * right;
} NODE;
Chỉ số cân bằng balance factor
Trang 102Cây AVL
Ảnh hưởng đến chỉ số cân bằng của nhánh cây liên quan
Sử dụng thao tác xoay phải, trái để cân bằng
Sinh viên tự tìm hiểu & đọc