Ctdl c4-cay

Preview:

Citation preview

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

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)

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

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

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

Tree – Ví dụ

Cây thư mục

5

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

Tree – Ví dụ

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

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

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

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)

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

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

Binary Tree – Ví dụ

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

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

Binary Tree – Ví dụ

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

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

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

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

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;};

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

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

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);

}}

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

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);}

}

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

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

}}

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

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

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

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

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

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

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

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

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)

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

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

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

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

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

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.

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);

}}

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

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

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;

}

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;

}

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

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

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

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

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

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

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

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

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

52

Xóa 51

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

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

53

Xóa 83

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

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

54

Xóa 36

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:

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

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:

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

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

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:

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

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;

}

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;}

}

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);

}}

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