65
Chương 4: CÂY (Tree)

Ctdl c4-cay

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Ctdl c4-cay

Chương 4: CÂY (Tree)

Page 2: Ctdl c4-cay

Chương 5: Cây (Tree)

Nội dung2

Cấu trúc cây (Tree) Cấu trúc cây nhị phân (Binary Tree) Cấu trúc cây nhị phân tìm kiếm (Binary Search Tree)

Page 3: Ctdl c4-cay

Chương 5: Cây (Tree)

Tree – Đinh nghia3

Cây là một tập gồm 1 hay nhiều nút T, trong đó có một 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

Page 4: Ctdl c4-cay

Chương 5: Cây (Tree)

Tree – Ví dụ 4

Sơ đồ tổ chức của một công ty

Công ty ACông ty A

R&DR&D Kinh doanhKinh doanh Taøi vuïTaøi vuï Saûn xuaátSaûn xuaát

TVTV CDCD AmplierAmplierNoäi ñòaNoäi ñòa Quoác teáQuoác teá

Chaâu aâuChaâu aâu MyõMyõ Caùc Caùc nöôùcnöôùc

Page 5: Ctdl c4-cay

Chương 5: Cây (Tree)

Tree – Ví dụ

Cây thư mục

5

Page 6: Ctdl c4-cay

Chương 5: Cây (Tree)

Tree – Ví dụ

Page 7: Ctdl c4-cay

Chương 5: Cây (Tree)

Tree – Ví dụ

Không phai cây

7

Trong cấu trúc cây không tồn tại chu trình

Page 8: Ctdl c4-cay

Chương 5: Cây (Tree)

Tree - Một số khái niệm cơ bản

Bậc của một nút (Degree of a Node of a Tree): Là số cây con của nút đó. Nếu bậc của một nút băng 0 thì nút đó

gọi là nút lá (leaf node) Bậc của một cây (Degree of a Tree):

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 (Root node): Là nút không có nút cha

Nút lá (Leaf node): Là nút có bậc băng 0

8

Page 9: Ctdl c4-cay

Chương 5: Cây (Tree)

Tree - Một số khái niệm cơ bản9

Nút nhánh: Là nút có bậc khác 0 và không phai là gốc

Mức của một nút (Level of a node): mức (gốc (T) ) = 0. gọi T1, T2, T3, ... , Tn là các cây con của T0 mức (T1) = mức (T2) = ... = mức (Tn) = mức (T0) + 1.

Chiều cao của cây (độ sâu) (Height – Depth of a tree): Là mức cao nhất của nút

Page 10: Ctdl c4-cay

Chương 5: Cây (Tree)

Nội dung10

Cấu trúc cây (Tree) Cấu trúc cây nhị phân (Binary Tree) Cấu trúc cây nhị phân tìm kiếm (Binary Search Tree)

Page 11: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Tree – Đinh nghia11

Cây nhị phân là cây mà mỗi nút có tối đa 2 cây con (cây có bậc là 2)

Cây con trai

Cây con phai

Hinh anh môt cây nhị phân

Page 12: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Tree – Ví dụ

Cây lệch trái và cây lệch phai

Page 13: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Tree – Ví dụ

Cây nhị phân đầy đủ (A full binary tree)

Page 14: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Tree – Ứng dụng

Cây biểu thức: được dùng để biểu diễn một biểu thức toán học

14

Page 15: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Tree – Một số tính chất

Số nút tại mức i ≤ 2i-1

Số nút lá ≤ 2h-1, với h là chiều cao của cây Số nút trong cây ≤ 2h-1, với h là chiều cao của cây Chiều cao của cây ≥ log2N, với N là số nút trong cây

15

Page 16: Ctdl c4-cay

Chương 5: Cây (Tree)

Trắc nghiệm

Số nút lá trong cây nhị phân với chiều cao 4 là: 2 4 6 8

Chiều cao tối thiểu của cây nhị phân với 31 nút là bao nhiêu? 4 7 5 3

16

Page 17: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Tree - Biểu diễn17

Sử dụng cấu trúc để lưu trữ các thông tin của một nút gồm: Dữ liệu của nút Địa chỉ nút gốc của cây con trái Địa chỉ nút gốc của cây con phai

Khai báo cấu trúc cây nhị phân:typedef struct Node{

DataType data; Node *pLeft, *pRight;

};

typedef struct Tree{

Node *pRoot;};

Page 18: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Tree – Khởi tạo cây

Khởi tạo cây rỗng:

void InitTree (Tree &t)

{

t.pRoot = NULL;

}

18

Page 19: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Tree - Duyệt cây nhi phân 19

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 - preorder (Node-Left-Right: NLR)

Duyệt theo thứ tự giữa - inorder (Left-Node-Right: LNR)

Duyệt theo thứ tự sau - postorder (Left-Right-Node: LRN) 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

Page 20: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Tree - Duyệt cây nhi phân

Duyệt theo thứ tự trước NLR (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 phai

Thủ tục duyệt có thể trình bày đơn gian như sau:

20

void NLR (Node* t){

if (t != NULL){

// Xư ly t tương ưng theo nhu câu

NLR(t->pLeft);NLR(t->pRight);

}}

Page 21: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Tree - Duyệt cây nhi phân NLR

21

A

B

D

H I

N

E

J K

O

C

F

L

P

G

M

AKết quả: B D H I N E J O K C F L P G M

Page 22: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Tree - Duyệt cây nhi phân

Duyệt theo thứ tự giữa LNR (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 phai

Thủ tục duyệt có thể trình bày đơn gian như sau:

22

void LNR(Node* t){

if (t != NULL){

LNR(t->pLeft);//Xư ly nut t theo nhu câu

LNR(t->pRight);}

}

Page 23: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Tree - Duyệt cây nhi phân LNR

23

A

B

D

H I

N

E

J K

O

C

F

L

P

G

M

HKết quả: D N I B J O E K A F P L C M G

Page 24: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Tree - Duyệt cây nhi phân

Duyệt theo thứ tự giữa LRN (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 phai 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 gian như sau:

24

void LRN(Node* t){

if (t != NULL){

LRN(t->pLeft);LRN(t->pRight);// Xư ly tương ưng t theo nhu câu

}}

Page 25: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Tree - Duyệt cây nhi phân LRN

25

A

B

D

H I

N

E

J K

O

C

F

L

P

G

M

HKết quả: N I D O J K E B P L F M G C A

Page 26: Ctdl c4-cay

Chương 5: Cây (Tree)

Trắc nghiệm

The order in which the nodes of this tree would be visited by a post-order traversal is

26

a) GCMBEJQDFKY

b) BCDFEJKYQMG

c) GCBEDFMJKQY

d) BDFECKJYQMG

Page 27: Ctdl c4-cay

Chương 5: Cây (Tree)

Trắc nghiệm

The order in which the nodes of this tree would be visited by a pre-order traversal is

27

a) GCMBEJQDFKYb) BCDFEJKYQMGc) BCDEFGKJMYQd) GCBEDFMJKQY

Page 28: Ctdl c4-cay

Chương 5: Cây (Tree)

Trắc nghiệm

For the binary tree, preorder and inorder traversals are as follows:

preorder: G C B E D F M J K Q Y

inorder: B C D E F G K J M Y Q

What the postorder for this tree?

28

G

C M

B E J Q

KFD Y

Page 29: Ctdl c4-cay

Chương 5: Cây (Tree)

Một số thao tác trên cây

Đếm số node Đếm số node lá Tính chiều cao ...

29

Page 30: Ctdl c4-cay

Chương 5: Cây (Tree)

Đếm số node

Thuật toán: Nếu Tree rỗng, Số node (Tree) = 0 Ngược lại, Số node (Tree) = 1 + Số node (Tree.Left) + Số node

(Tree.Right)

30

Page 31: Ctdl c4-cay

Chương 5: Cây (Tree)

Đếm số node lá

Thuật toán: Nếu Tree rỗng, Số nút lá (Tree) = 0 Nếu Tree là nút lá, Số nút lá (Tree) = 1 + Số nút lá (Tree.Left) +

Số nút lá (Tree.Right) Nếu Tree không là nút lá, Số nút lá (Tree) = Số nút lá

(Tree.Left) + Số nút lá (Tree.Right)

31

Page 32: Ctdl c4-cay

Chương 5: Cây (Tree)

Tính chiều cao

Thuật toán: Nếu Tree rỗng, Height(Tree) = 0 Ngược lại, Height(Tree) = 1 + max(Height(Tree.Left),

Height(Tree.Right))

32

Page 33: Ctdl c4-cay

Chương 5: Cây (Tree)

Nội dung33

Cấu trúc cây (Tree) Cấu trúc cây nhị phân (Binary Tree) Cấu trúc cây nhị phân tìm kiếm (Binary Search Tree)

Page 34: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree - Đinh nghia34

Là cây nhị phân Giá trị của một node bất kỳ luôn lớn

hơn giá trị của tất ca các node bên trái và nhỏ hơn giá trị tất ca các node bên phai

Nút có giá trị nhỏ nhất năm ở trái nhất của cây

Nút có giá trị lớn nhất năm ở phai nhất của cây

7777

33 3636

11 66 1515 4040

232344

Page 35: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Biểu diễn35

Cấu trúc dữ liệu của CNPTK là cấu trúc dữ liệu biểu diễn cây nhị phân

Thao tác duyệt cây trên CNPTK hoàn toàn giống như trên cây nhị phân Chú ý: 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

Page 36: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Duyệt cây36

25

10

3

1 6

5

18

12 20

13

37

29

35

32

50

41

Duyệt inorder: 1 3 5 6 10 12 13 18 20 25 29 32 35 37 41 50

Duyệt giữa trên CNPTK

Page 37: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Duyệt cây37

25

10

3

1 6

5

18

12 20

13

37

29

35

32

50

41

Duyệt postorder: 1 5 6 3 13 12 20 18 10 32 35 29 41 50 37 25

Duyệt sau trên CNPTK

Page 38: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Duyệt cây38

25

10

3

1 6

5

18

12 20

13

37

29

35

32

50

41

Duyệt preorder: 25 10 3 1 6 5 18 12 13 20 37 29 35 32 50 41

Duyệt trước trên CNPTK

Page 39: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Thêm39

40401515446611363633

7 36 3 1 6 4 15 40

7777 Nếu node cần thêm < node đang xét thì thêm về bên trái.

Ngược lại thì thêm về bên phải.

Page 40: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Thêm

Thêm một phần tử vào cây:

40

void InsertNode(Node *T, DataType X){

if (T == NULL){

T = new Node;T->data = XT->pLeft=T->pRight=NULL;

}else{

if(X > T->data)InsertNode(T->pRight,X);

else if(X < T->data) InsertNode(T->pLeft,X);

}}

Page 41: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Tìm kiếm41

25

10

3

1 6

5

18

12 20

13

37

29

35

32

50

41

Tìm kiếm 13

Khác nhauGiống nhauNode gốc nhỏ hơnNode gốc lớn hơn

Tim thấySố node duyệt: 5

Tim kiếm trên CNPTK

Page 42: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Tìm kiếm42

25

10

3

1 6

5

18

12 20

13

37

29

35

32

50

41

Tìm kiếm 14

Khác nhauNode gốc nhỏ hơnNode gốc lớn hơn

Không tim thấySố node duyệt: 5

Tim kiếm trên CNPTK

Page 43: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Tìm kiếm

Tìm một phần tử x trong CNPTK (dùng đệ quy):

43

Node* searchNode(Node *T, DataType X){

if (T){

if(T->data == X)return T;

if(T->data > X)return searchNode(T->pLeft,

X);return searchNode(T->pRight, X);

}return NULL;

}

Page 44: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Tìm kiếm

Tìm một phần tử x trong CNPTK (dùng vòng lặp):

44

Node* searchNode(Node* T, DataType x){

Node *p = T;while (p != NULL){

if(x == p->data) return p;else if(x < p->data) p = p-

>pLeft;else p = p->pRight;

}return NULL;

}

Page 45: Ctdl c4-cay

Chương 5: Cây (Tree)

Bài tập

Viết các hàm: Đếm số nút trên cây: CountNode Đếm số nút lá: CountLeaf Đếm số nút trong: CountInnerNode 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 Xuất các số nguyên tố trên cây

45

Page 46: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Hủy một phần tử có khóa X

46

Việc hủy một phần tử X ra khỏi cây phai bao đam điều kiện ràng buộc của CNPTK

Có 3 trường hợp khi hủy nút X có thể xay ra: X là nút lá X chỉ có 1 con (trái hoặc phai) X có đủ ca 2 con

Page 47: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Hủy một phần tử có khóa X

47

Trường hợp 1: X là nút lá Chỉ đơn gian hủy X vì nó không móc nối đến phần tử nào khác

44

18 88

13 37 59 108

15 23 40 55 71

Hủy X=40

Page 48: Ctdl c4-cay

Chương 5: Cây (Tree)

23

Binary Search Tree – 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ước khi hủy X ta móc nối cha của X với con duy nhất của nó

48

44

18 88

13 37 59 108

15 23 55 71

Hủy X=37

Page 49: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Hủy một phần tử có khóa X

Trường hợp 3: X có đủ 2 con: Không thể hủy trực tiếp do X có đủ 2 con Hủy gián tiếp:

Thay vì hủy X, ta sẽ tìm một phần tử thế mạng Y. Phần tử

này có tối đa một con

Thông tin lưu tại Y sẽ được chuyển lên lưu tại X

Sau đó, nút bị hủy thật sự sẽ là Y giống như 2 trường hợp

đầu Vấn đề: chọn Y sao cho khi lưu Y vào vị trí của X, cây vẫn

là CNPTK

49

Page 50: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Hủy một phần tử có khóa X

Cách chọn phần tử thế mạng:

Phần tử nhỏ nhất (trái nhất) trên cây con phải (của nút muốn

xóa)

Phần tử lớn nhất (phai nhất) trên cây con trái (của nút muốn

xóa)

Việc chọn lựa phần tử nào là phần tử thế mạng phụ thuộc vào ý thích của người lập trình

Ở đây, ta sẽ chọn phần tử nhỏ nhất trên cây con phải làm phần tử thế mạng

50

Page 51: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Hủy một phần tử có khóa X

Trường hợp 3: X có đủ 2 con: Khi hủy phần tử X=18 ra khỏi cây:

51

4444

8888

1313 3737 5959 108108

4040 5555 7171

Hủy X=18

3030

2323

1818X

Chọn phần tử nhỏ nhất trên cây con phải phần tử 23 là phần tử thế mạng

2323

Page 52: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Hủy một phần tử có khóa X

52

Xóa 51

Page 53: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Hủy một phần tử có khóa X

53

Xóa 83

Page 54: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Hủy một phần tử có khóa X

54

Xóa 36

Page 55: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Hủy một phần tử có khóa X

55

Xóa nút gốc:

Page 56: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Hủy một phần tử có khóa X

56

Xóa nút gốc: 42 là thế mạng

Page 57: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Hủy một phần tử có khóa X

57

Kết qua xóa:

Page 58: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Hủy một phần tử có khóa X

58

Xóa gốc 42

Page 59: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Hủy một phần tử có khóa X

Xóa gốc 42 45 thế mạng

59

Page 60: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Hủy một phần tử có khóa X

60

Kết qua xóa:

Page 61: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Hủy một phần tử có khóa X

Các hàm dùng để hủy 1 phần tử:

Hàm delNode tra về giá trị 1, 0 khi hủy thành công hoặc không

có X trong cây:

int delNode (Node* &T, DataType X)

Hàm searchStandFor tìm phần tử thế mạng q và gán dữ liệu của

q cho nút muốn xóa p

void searchStandFor(Node* &p, Tree &q)

61

Page 62: Ctdl c4-cay

Chương 5: Cây (Tree)

62

Binary Search Tree – Hủy một phần tử có khóa X

Hủy một nútint delNode(Node* &T, DataType X)

{

if (T == NULL) return 0;

if (T->data > X) return delNode(T->pLeft, X);

if (T->data < X) return delNode(T->pRight, X);

Node *p = T;

if (T->pLeft == NULL) T = T->pRight;

else if (T->pRight == NULL) T = T->pLeft;

else // T có đủ 2 con

searchStandFor(p, T->pRight);

delete p;

}

Page 63: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Hủy một phần tử có khóa X

Tìm phần tử thế mạng (nhỏ nhất trên cây con phải):

63

void searchStandFor(Node* &p, Node* &q){

if (q->pLeft != NULL)searchStandFor (p, q->pLeft);

else{

p->data = q->data; p = q; q = q->pRight;}

}

Page 64: Ctdl c4-cay

Chương 5: Cây (Tree)

Binary Search Tree – Hủy toàn bộ cây

Việc toà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 phai rồi mới hủy nút gốc

64

void removeTree(Node* &T){

if (T){

removeTree(T->pLeft); removeTree(T->pRight); delete(T);

}}

Page 65: Ctdl c4-cay

Chương 5: Cây (Tree)

Bài tập

Viết các hàm: Đếm số nút có đúng 1 con Đếm số nút có đúng 2 con Đếm số nguyên tố trên cây Tính tổng các nút có đúng 1 con Tính tổng các nút có đúng 2 con Tính tổng các số chẵn Nhập x, tìm giá trị nhỏ nhất trên cây mà lớn hơn x Xuất số nguyên tố nhỏ nhất trên cây Nhập x, tìm x trên cây, nếu tìm thấy x thì cho biết x có bao

nhiêu con Xóa 1 nút

65