Tree - Khoa Công Nghệ Thông Tin

Download Report

Transcript Tree - Khoa Công Nghệ Thông Tin

Cây
Các khái niệm và thuật ngữ cơ
bản
Cây nhị phân và cây nhị phân
tìm kiếm(BST)
Cây nhị phân tìm kiếm cân
bằng(AVL)
1
Các khái niệm và thuật ngữ cơ bản
2
Các khái niệm và thuật ngữ cơ bản
3
Các khái niệm và thuật ngữ cơ bản
Định nghĩa cấu trúc cây

một cây T (Tree) là:
Một tập các phần tử, gọi là các nút (Node): P1 , P2,…,
PN
Nếu N = 0, cây T gọi là cây rỗng (NULL)
Nếu N > 0:
 Tồn tại duy nhất một nút Pk gọi là gốc của cây
 Các nút còn lại được chia thành m tập không
giao nhau: T1, T2, … , Tm
 Mỗi Ti là 1 cây con của cây T
4
Các khái niệm và thuật ngữ cơ bản
Định nghĩa cấu trúc cây
Cây T
Nút gốc
Cây con T3
a
Cây con T4
c
d
k
j
i
Cây T rỗng (NULL)
g
h
f
e
b
Cây con T2
Cây con T1
5
Các khái niệm và thuật ngữ cơ bản
Định nghĩa cấu trúc cây
Cây T
a
j
i
c
g
h
f
e
k
d
b
Cây con T1
Cây con T4
Cây con T2
Cây con T3
6
Các khái niệm và thuật ngữ cơ bản
Định nghĩa cấu trúc cây

Các tính chất của cây:
Nút gốc không có nút cha
Mỗi nút khác chỉ có một nút cha
Mỗi nút có thể có nhiều nút con
 không có chu trình
7
Các khái niệm và thuật ngữ cơ bản
Các thuật ngữ liên quan
Nút (Node) là một phần tử trong cây. Mỗi nút có thể
chứa 1 dữ liệu bất kỳ.
Nhánh (Branch): là đoạn nối giữa 2 nút
Nút cha (Parent Node)
Nút con (Child Node)
Nút anh em (Sibling Node): là những nút có cùng nút
cha
 Bậc của một nút pi là số nút con của nút pi

8
Các khái niệm và thuật ngữ cơ bản
Các thuật ngữ liên quan
Nút gốc (Root Node): là nút không có nút cha
Nút lá (Leaf Node): là nút không có nút con hay nút có
bậc = 0
Nút nội (Internal Node): là nút có nút cha và có nút con
Bậc của cây: là bậc lớn nhất của các nút trong cây

 Bậc của cây T = max { bậc pi / pi Є T}
 đường đi(path) giữa nút pi đến nút pj: là dảy các nút
liên tiếp từ pi đến pj sao cho giữa hai nút kề nhau đều
có nhánh.
9
Các khái niệm và thuật ngữ cơ bản
Các thuật ngữ liên quan
 Mức (level)
o Mức (p) = 1 nếu p = root
o Mức (p) = 1 + mức ( cha (p)) nếu p != root
Chiều cao của cây (height - hT): là đường đi dài nhất từ
nút gốc đến nút lá (hay là mức lớn nhất của nút lá trong
cây)
hT = max { Path(root, pi) / pi là nút lá Є T}
10
Các khái niệm và thuật ngữ cơ bản
Các thuật ngữ liên quan
h=4
11
Các khái niệm và thuật ngữ cơ bản
Các thuật ngữ liên quan
Level 1
-- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --
Level 2
--- --- --- --- --- --- --- --- ---
Level 3
-- --- --- --- --- --- ---
C
B
--- --
--- --- --- ---
D
Parents: A, B, F
Children: B, E, F, C, D, G, H, I
Siblings: {B, E, F} ; {C, D} ; {G, H, I}
Leaves: E, C, D, G, H, I
Internal Nodes: B, F
A
E
--- --- --- --- -
Branch
AF
--- --- --
G
--
F
H
Branch
FI
-- ---
I
12
Cây nhị phân
13
14
Cây nhị phân
Lưu trữ cây
Có 2 cách tổ chức cây nhị phân:
 Lưu trữ bằng mảng
 Lưu trữ bằng con trỏ cấu trúc
15
Cây nhị phân
Cách lưu trữ cây, sử dụng mảng
struct NODE
{
DataType Data;
int left; // chỉ số nút con trái
int right; // chỉ số nút con phải
};
NODE TREE[n]; // cây nhị phân có n nút
16
Cây nhị phân
Cách lưu trữ cây, sử dụng con trỏ
BIN_TREE
pRoot
Count
Data
pLeft
pRight
NODE
Data
pLeft
pRight
........
Data
pLeft
pRight
........
17
Cây nhị phân
Cách lưu trữ cây, sử dụng con trỏ
struct NODE
{
DataType Data;
NODE *pLeft; // con trỏ đến nút con trái
NODE *pRight;// con trỏ đến nút con phải
};
struct TREE
{
int Count; // số nút trong cây
NODE *pRoot; //con trỏ đến nút gốc
};
18
19
Phép duyệt cây
20
21
(NLR) (NLR)
Duyệt gốc trước
Duyệt gốc giữa(LNR)
Duyệt gốc(LRN)
sau(LRN)
22
phép duyệt cây
A
Cài đặt
void NLR(const NODE * pCurr)
{
if(pCurr == NULL)
return;
xử lý nút gốc pCurr
NLR(pCurr  pLeft);
NLR(pCurr  pRight);
}
B
C
D
A B C
F
D
E
F
Processing order
A
B
C
E
E
D
F
23
phép duyệt cây
A
Cài đặt
void LNR(const NODE * pCurr)
{
if(pCurr == NULL)
return;
LNR(pCurr  pLeft);
xử lý nút gốc pCurr
LNR(pCurr  pRight);
}
B
C
C
D
B D
F
A
E F
Processing order
A
B
C
E
E
D
F
24
phép duyệt cây
A
Cài đặt
void LRN(const NODE * pCurr)
{
if(pCurr == NULL)
return;
LRN(pCurr  pLeft);
LRN(pCurr  pRight);
xử lý nút gốc pCurr
}
B
C
C
D
F
D B
F
E A
Processing order
A
B
C
E
E
D
F
25
Bài tập
BT1> Cho cây nhị phân các số nguyên. Hãy
viết hàm đếm số lượng số chẵn có trong cây.
Hãy viết hàm đếm số lượng nút lá trong cây
bằng PP đệ quy và không đệ quy. Viết hàm đếm
số lượng nút trong cây có khóa lớn hơn x.
BT2> cho cây nhị phân các số thực. Hãy viết
hàm tính tổng các giá trị dương có trong cây.
Viết hàm đếm số lượng nút trong cây có giá trị
nhỏ hơn x.
26
Bài tập
BT3> Cho cây nhị phân các phân số. Viết
hàm đếm số lượng nút có đúng 2 con.
BT4>Cho cây nhị phân tọa độ các điểm
trong mặt phẳng Oxy. Viết hàm tính chiều
cao của cây.
27
Cây nhị phân tìm kiếm
BST – Binary search tree
28
29
30
Cây nhị phân tìm kiếm
Ví dụ: cho biết hình nào thảo BST? Hình
nào không thỏa BST? Tại sao?
17
17
17
(b)
22
6
19
19
(c)
(a)
17
17
6
6
3
3
(d)
19
22
(e)
31
Cách lưu trữ cây BST giống như cây nhị phân
32
33
Các thao tác trên cây BST
o Tạo lập cây rỗng
o Kiểm tra cây rỗng
o Tìm kiếm phần tử
o Thêm một phần tử
o Xóa một phần tử
o Sắp xếp dữ liệu
o Quay cây
34
Tạo lập cây rỗng
void BSTCreate(TREE &t)
{
t.Count = 0; // số nút trong cây
t.pRooot = NULL; // con trỏ đến nút gốc
}
35
kiểm tra cây rỗng
int BSTIsEmpty(TREE &t)
{
if(t.pRooot = = NULL)
return 1;
return 0;
}
36
Tìm kiếm phần tử
Ví dụ tìm kiếm phần tử 25
pRoot
40
32
24
4
Tìm thấy,
dừng
65
36
25
75
70
30
37
Tìm kiếm phần tử
Ví dụ tìm kiếm phần tử 31
pRoot
40
32
24
4
65
36
25
75
70
30
NULL, không tìm thấy
38
39
Tìm kiếm phần tử
Cài đặt
NODE *BSTSearch(const NODE * pCurr, int Key)
{
if (pCurr == NULL)
return NULL; // không tìm thấy
if (pCurr  Data == Key)
return pCurr; // Tìm thấy
else if (Key < pCurr Data) // tìm trong cây con trái
return BSTSearch(pCurrpLeft, Key);
else
// tìm trong cây con phải
return BSTSearch(pCurr  pRight,key);
}
40
Thêm phần tử
Ví dụ thêm phần tử 26
pRoot
40
32
24
4
NULL, kết thúc tìm
ở đây
65
36
27
75
70
30
41
Thêm phần tử
Ví dụ thêm phần tử 26
pRoot
40
32
24
4
65
36
27
26
75
70
30
42
Thêm phần tử
Ví dụ thêm phần tử 27
pRoot
40
32
24
4
Tìm thấy, không
thêm nữa
65
36
27
75
70
30
43
44
Thêm phần tử
Cài đặt
int BSTInsert(NODE *&pCurr, int newKey)
{
if (pCurr == NULL)
{
pCurr = new NODE; // tạo nút mới
pCurr Data = newKey;
pCurrpLeft = pCurrpRight = NULL;
return 1;// thêm thành công
}
if ( newKey < pCurr Data) // thêm vào cây con trái
return BSTInsert(pCurrpLeft, newKey);
else if (newKey > pCurrData) // thêm vào cây con phải
return BSTInsert(pCurr  pRight, newKey);
else return 0; // trùng khóa, không thêm nữa
}
45
Thêm phần tử
Có thể cài đặt cách khác như sau
int BSTInsert(TREE &t, int newKey)
{
if (t == NULL)
{
t = new NODE; // tạo nút mới
t Data = newKey;
tpLeft = tpRight = NULL;
return 1;// thêm thành công
}
if ( newKey < t Data) // thêm vào cây con trái
return BSTInsert(tpLeft, newKey);
else if (newKey > tData) // thêm vào cây con phải
return BSTInsert(t  pRight, newKey);
else return 0; // trùng khóa, không thêm nữa
}
Với t được khai báo: typedef struct NODE *TREE;
46
47
Gán liên
kết ở
nút cha
thành
NULL
48
49
Xóa một đỉnh khỏi cây tìm kiếm
Ví dụ xóa phần tử 25(chỉ có nút con phải là 30)
40
32
P
24
PCurr
40
65
32
36
25
75
24
70
30
65
36
30
75
70
Liên kết = nút
con phải
PpRight = pCurrpRight
Delete pCurr
50
Xóa một đỉnh khỏi cây tìm kiếm
Ví dụ xóa phần tử 75(chỉ có nút con trái là 70)
40
65 P
32
24
40
36
32
75
24
Liên kết = nút
con trái
65
36
70
PCurr
25
70
30
25
30
PpRight = pCurrpLeft
Delete pCurr
51
52
Cách 1
53
Cách 2
54
Xóa một đỉnh khỏi cây tìm kiếm
Xóa 1 phần tử pCurr có 2 nút con:
• Thay vì xóa trực tiếp nút pCurr:
• Ta tìm phần tử thay thế p,
• Copy nội dung của p sang pCurr
• Xóa nút p
• Phần tử thay thế p:
• là phần tử lớn nhất trong cây con bên trái hoặc
là phần tử nhỏ nhất trong cây con bên phải
=> Phần tử p có nhiều nhất là 1 nút con
55
56
57
58
59
Bài tập
 Hãy tạo cây BST với thứ tự các từ khóa nhập
vào như sau: 40, 32, 65, 75,70, 24,4, 36, 25, 30.
Hãy vẽ lại cây cho cả 2 trường hợp khi xóa nút
40.
60
Bài tập
BT1> Tổ chức một cây nhị phân tìm kiếm trong đó mỗi phần
tử chứa thông tin dữ liệu là số nguyên. Nguời dùng sẽ nhập
các giá trị nguyên từ bàn phím. Với mỗi giá trị nguyên đuợc
nhập vào, giá trị đó đuợc thêm vào cây nhị phân tìm kiếm mà
vẫn dảm bảo cây sau khi thêm vẫn là cây nhị phân tìm kiếm.
Nếu nguời dùng nhập vào giá trị -1, quá trình nhập dữ liệu sẽ
kết thúc. Cây ban dầu là cây rỗng (chua có nút nào). Sau dó,
in ra các phần tử dang có trên cây bằng phuong pháp duyệt
truớc. Cho nguời dùng nhập vào 1 giá trị nguyên từ bàn phím,
cho biết giá trị này có trong cây hay không. Nếu có, cho biết
nút đó có độ cao bao nhiêu. Sau dó, xóa nút khỏi cây, xuất
cây sau khi xóa bằng phuong pháp duyệt truớc.
61
Bài tập
62
Bài tập
63
Bài tập
64
Cây AVL
(cây nhị phân tìm kiếm cân bằng)
65
66
67
68
-1
1
69
Mô tả cấu trúc cây AVL
20
Hệ số
cân
bằng
của các
nút
trong
cây AVL
1
1
10
30
0
-1
0
15
0
26
40
0
0
25
27
70
Mô tả cấu trúc cây AVL
AVL_TREE
pRoot
Count
Data
Bal
pLeft
pRight
Nút gốc của
cây con trái
Nút gốc của
cây con phải
NODE
Data
Bal
Data
Bal
pLeft
pRight
pLeft
pRight
........
........
71
Mô tả cấu trúc cây AVL
struct NODE
{
DataType Data;
NODE * pLeft;
NODE *pRight;
int Bal;
};
Struct AVLTREE
{
int Count;
NODE *pRoot;
};
72
73
74
75
76
77
78
79
80
P
18
8
2
35
RR
35
20
PpRight = P1 pLeft
P1pLeft = P
P1
1
50
18
1
8
50
20
55
55
81
82
83
84
R
QpLeft = RpRight
RpRight = Q
85
R
Q
PpRight = RpLeft
RpLeft = P
86
87
88
89
90
91
92
93
Bài tập
 Tạo cây AVL với các khóa lần lượt
là: 30, 20, 10. Sau đó thêm lần lượt
các khóa: 15, 40, 25, 27, 26, 5, 13, 14
vào cây trên.

94
Bài tập
BT3>Tổ chức một cây cân bằng AVL trong dó mỗi node
trên cây chứa thông tin dữ liệu nguyên. Nguời dùng sẽ
nhập các giá trị nguyên từ bàn phím. Với mỗi giá trị
nguyên duợc nhập vào, phải tạo cây AVL theo dúng
tính chất của nó. Nếu nguời dùng nhập -1 quá trình
nhập dữ liệu sẽ kết thúc. Sau dó, xuất thông tin các
node trên cây. Khi chuong trình kết thúc, tất cả các
node trên cây bị xóa bỏ khỏi bộ nhớ
95