You are on page 1of 25

Tree

Giảng viên: Tạ Việt Cường


Phòng HMI – Khoa CNTT

1
Ôn tập bài trước
Với mỗi câu khẳng định sau, trả lời Đúng/Sai và giải thích:
 Sắp xếp lựa chọn độ phức tạp tốt nhất là O(N)
 Sắp xếp chèn độ phức tạp tốt nhất là O(N)
 Merge-sort là thuật toán sắp xếp ổn định
 Quick-sort là thuật toán sắp xếp ổn định

2
Ôn tập bài trước

 Bài 1: Vẽ cây gọi đệ qui mergesort với A = [ 2, 5, 1, 3, 9, 8]


Sử dụng pseudocode sau:
merge_sort(A):
if size(A) == 1: return A
N = size(A)

tạo l1 = [ A[0], A[1] ,..., A[N/2-1] ]


tạo l2 = [ A[N/2], ..., A[N-1] ]
l1 = merge_sort(l1)
l2 = merge_sort(l2)
return merge(l1, l2)

3
Ôn tập bài trước
Bài 2: Tìm kiếm nhị phân - đệ qui
A - dãy được sắp xếp tăng dần
x - giá trị cần tìm kiếm
left, right -

binary_search(A, x, left, right)


if right > left: return false
m = (left + right) /2
c = A[m]
if c == x: return true
if c < x: return binary_search(A, x, m+1, r)
else: return binary_search(A, x, l, m-1)
Cho A = [1, 5, 6, 10, 15, 16, 20, 22, 25]
Viết chuỗi hàm gọi đệ qui binary_search(A, 16, 0, 8)

Tính độ phức tạp theo N - là số phần tử của dãy A


Điều kiện để tìm kiếm nhị phân trả về kết quả đúng là gì

4
Ôn tập bài trước

Bài 3: Cho pseudocode sau quick_sort(a, l, r) // Sắp xếp dãy a từ l đến r


if (l >= r) return;
x = a[r]
i = l-1
j = r
while (true) {
while (a[++i] < x)
if (i == r) break;
while(x < a[--j])
if (j == l) break;
if (i >= j) break;
swap(a[i], a[j]);
}
swap(a[i], a[r]);
quicksort(a, l, i-1);
quicksort(a, i+1, r);

Dãy A = [ 5, 1, 6, 3, 1, 2, 4, 8].
Tính giá trị của i, và A sau lời gọi quick_sort(A, 0, 7)
5
Tree
 Cấu trúc phân nhánh có thứ tự (hierarchical structure)
 Gồm có:
 nodes
 liên kết giữa các nốt, từ cao đến thấp
 Ví du:
 Cấu trúc thư mục: Folder: Study

DSA C++ OOP

week1 week2 week3 week1 week2 week1 week2

6
Cái khái niệm về Tree (1)
 root = A A

 internal node: node có ít


nhất 1 node con = A, B, F,
B C D
C
 external node - leaf node:
node lá: E, I, J, K, G, H, D
E F G H

I J K

7
Cái khái niệm về Tree (2)
 parent of a node: node ngay phía trên
 parent of B: A
 parent of E: B
 parent of A = -1
 Chú ý: mỗi node có tối đa 1 parent
 children of node: có thể có nhiều
 children of A: B, C, D
 children of B: E,F
 ancestors of a node:
 ancestors of F: B, A
A
 descendant of a node:
 siblings: same parent
 E-F
 B-C-D B C D

E F G H

I J K 8
Cái khái niệm về Tree (3)
 Depth of a node: Độ sâu của node
 Tính bằng số lượng ancestors
 depth of A = 0
 depth of B = 1
 depth of E = 2
A
 Height of tree: Độ cao
 Maximum depth
 Path: Đường đi B C D
 đi từ A đến C: E-B-A-C
 đi từ I đến B: I F B
E F G H

I J K 9
Cái khái niệm về Tree (4)

 Subtree: cây con


 gồm có node đó và các node descendants của nó
 subtree tại C: C, G, H
 subtree tại B: B, F, I, J, K

B C D

E F G H

10
I J K
Cách biểu diễn Tree
 Mở rộng từ linked-list
root
Template <class Item>
class Node {
Item data;
Node* parent;
A
Vector<Node*> children;
}

Node<Item>* root;
B C D

E F G
11
Cách tính depth

Depth(v): number of ancestors of v

Input:
T - Cây
v - Node cần tính depth
Algorithm depth(T, v):
if v is the root of T then
return 0;
else
return 1 + depth(T, w), where w is the
parent of v in T;

12
Hai cách duyệt cây

 Tree traversal: Duyệt cây


 In ra các nốt theo 1 thứ tự nhất định
 Preorder Traversal:
 In ra node rồi in ra các children của nó, đệ qui
 Postorder Traversal:
 Ngược lại

13
Preorder Traversal
 In ra node, rồi in ra các children của nó, đệ qui

Algorithm preOrder(v)
visit(v);
1 for each child w of v
A
preorder (w);
2 5 6
Chú thích: visit(v) thực hiện các
B C D phép toán tại node v (ví dụ in ra)

3 4 7 8

E F T K

A, B, E, F, C, D, T, K 14
Postorder Traversal
 In ra các nodes ở cây con, rồi in ra node gốc, đệ qui
 Nhiều node con: in ra từ trái sang phải

Algorithm postOrder(v)
8
A for each child w of v
postOrder (w);
3 4 7 visit(v);
B C D

1 2 5 6

E F T K

E, F, B, C, T, K, D, A 15
Ví dụ
a

b c

f
d e

g j
h i

Preorder =
Post order =

16
Binary Tree - Cây nhị phân
 Cây nhị phân:
 Mỗi node có tối đa 2 nodes con
 Chia thành: left child - cây con trái
right child - cây con phải

B C

D E F G

17
H I
Ứng dụng
 Binary search tree: left child < node < right child với mọi
node
 Dùng để tìm kiếm nhanh:
12
 x có xuất hiện trong tree
 x == root: có
2 20
 x < root: tìm trong left tree
 x > root: tìm trong right tree
 O=? 1 8 16 32

5 10

18
Decision Tree
 Cây quyết định: một lớp các thuật toán quan trong trong
machine learning/artificial intelligent
 Ví dụ bài toán: dự đoán điểm thi DSA cuối kì
 Dữ liệu mỗi sinh viên bao gồm:
 Điểm c++, LTNC, hw1, hw2, mid-term
 Đi theo cây thì có thể đoán được điểm số thi cuối kì

c++

<8 >=8

hw2
.....
<10 >=10

midterm 10
<8 >= 8
8 9
19
Duyệt cây nhị phân
 Inorder traversal
 Thăm cây con trái
 Node hiện tại
 Thăm cây con phải
4
Algorithm inOrder(v)
A
if hasLeft (v)
inOrder (left (v));
2 6 visit(v);
B C if hasRight (v)
1
inOrder (right (v));
3 5
D E F

D, B, E, A, F, C 20
Cây biểu thức nhị phân
Algorithm printExpression(v)
 Internal node: phép toán if hasLeft (v)
 Leaf node: biến số print(“(’’);
inOrder (left(v));
((2 × (a − 1)) + (3 × b)) print(v.element ());
if hasRight (v)
+ inOrder (right(v));
print (“)’’);
× ×

2 3 b
a 1
21
Cây nhị phân cân bằng
 Với mọi node, chênh lệch chiều cao của cây con trái và cây con
phải không quá 1

3 3
A A
2 0 2 1
B C B C
1 0 0 0 0
1
D E D E F G

0 0
F G H

Unbalanced Balanced

22
Khai báo Binary Tree c++, sử
dụng con trỏ
class Node {
Item data;
Node* parent;
Node* leftChild;
A
Node* rightChild;
}

Node* root; B C

23
Khai báo Binary Tree, sử dụng
mảng
 Dùng mảng với qui ước
 Node thứ i thì left child là node thứ 2i và right child là
node 2*i+1

i=1 i=2 i=3 i=4 i=5 i=6 i=7 i=8


A B D -1 -1 C E -1
1
A

2 3
B D

4 5 6 7 24
-1 -1 C E
+
× ×

a b −

b c
c a

25

You might also like