Tải bản đầy đủ (.ppt) (34 trang)

CẤU TRÚC DỮ LIỆU CÂY (TREE) pot

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (673.83 KB, 34 trang )

CẤU TRÚC DỮ LIỆU CÂY
(TREE)
Thạc sĩ: HUỲNH PHƯỚC DANH
Email:
ThS. Huỳnh Phước Danh Cấu trúc dữ liệu và giải thuật
- 2 -
KHÁI NIỆM CÂY
Cây là một tập hợp các phần tử (các nút) được tổ chức và có
các đặc điểm sau:

Hoặc là một tập hợp rỗng (cây rỗng).

Hoặc là một tập hợp khác rỗng trong đó có một nút
duy nhất được làm nút gốc (Root’s Node), các nút còn lại
được phân thành các nhóm trong đó mỗi nhóm lại là một
cây gọi là cây con (Sub-Tree).
Như vậy, một cây con có thể là một tập rỗng các nút và
cũng có thể là một tập hợp khác rỗng trong đó có một nút
làm nút gốc cây con.
ThS. Huỳnh Phước Danh Cấu trúc dữ liệu và giải thuật
- 3 -
CÁC KHÁI NIỆM

Bậc của một nút: là số
cây con của nút đó.

Nút gốc: là nút không có
nút cha.

Nút lá: là nút có bậc bằng
0.



Nút nhánh: là nút có bậc
khác 0 và không phải là
gốc.
2
2
2
110
0
0
0
ThS. Huỳnh Phước Danh Cấu trúc dữ liệu và giải thuật
- 4 -
CÁC KHÁI NIỆM
Mức 3
Mức 2
Mức 1
Mức 0

Độ dài đường đi từ
gốc đến nút x: là số
nhánh cần đi qua kể
từ gốc đến x.

Độ cao của cây: Độ
dài đường đi từ gốc
đến nút lá ở mức
thấp nhất.
ThS. Huỳnh Phước Danh Cấu trúc dữ liệu và giải thuật
- 5 -

CÂY NHỊ PHÂN
Cây nhị phân là cây rỗng hoặc là cây mà mỗi nút có tối đa hai
nút con (cây có bậc bằng 2) . Hơn nữa các nút con của cây
được phân biệt thứ tự rõ ràng, một nút con gọi là nút con trái
và một nút con gọi là nút con phải. Ta qui ước vẽ nút con trái
bên trái nút cha và nút con phải bên phải nút cha, mỗi nút con
được nối với nút cha của nó bởi một đoạn thẳng.
ThS. Huỳnh Phước Danh Cấu trúc dữ liệu và giải thuật
- 6 -
CÂY NHỊ PHÂN
A
A
B
B
C
C
D
D
E
E
F
F
H
H
G
G
K
K
Root
Root

A
A
B
B
C
C
D
D
E
E
F
F
H
H
G
G
K
K
ThS. Huỳnh Phước Danh Cấu trúc dữ liệu và giải thuật
- 7 -
CẤU TRÚC DỮ LIỆU CÂY NHỊ PHÂN
struct BinT_Node
{
<Kiểu dữ liệu> info;
BinT_Node *left; // Vùng liên kết quản
lý địa chỉ nút gốc cây con trái
BinT_Node *right; // Vùng liên kết quản
lý địa chỉ nút gốc cây con phải
};
Info

Info
Left
Left
Right
Right
BinT_Node
ThS. Huỳnh Phước Danh Cấu trúc dữ liệu và giải thuật
- 8 -
DUYỆTCÂY NHỊ PHÂN

Duyệt theo thứ tự nút gốc trước (Preorder):
Theo cách duyệt này thì nút gốc sẽ được duyệt trước, sau
đó mới duyệt đến hai cây con. Căn cứ vào thứ tự duyệt hai
cây con mà chúng ta có hai cách duyệt theo thứ tự nút gốc
trước:

Duyệt nút gốc, duyệt cây con trái, duyệt cây con phải
(Root – Left – Right)

Duyệt nút gốc, duyệt cây con phải, duyệt cây con trái
(Root – Right – Left)
ThS. Huỳnh Phước Danh Cấu trúc dữ liệu và giải thuật
- 9 -
DUYỆTCÂY NHỊ PHÂN
A, B, C, D, E, F, H, K, L, M
A
A
B
B
H

H
C
C
D
D
K
K
L
L
F
F
M
M
E
E
Thuật giải
void Traversal_NLR(BinT_Node* Root)
{
if (Root = = NULL) return;
cout << Root->info << “ “;
Traversal_NLR(Root->left);
Traversal_NLR(Root->right);
}
ThS. Huỳnh Phước Danh Cấu trúc dữ liệu và giải thuật
- 10 -
DUYỆTCÂY NHỊ PHÂN

Duyệt theo thứ tự nút gốc giữa (Inorder):
Theo cách duyệt này thì chúng ta duyệt một trong hai cây
con trước rồi đến duyệt nút gốc và sau đó mới duyệt cây

con còn lại. Căn cứ vào thứ tự duyệt hai cây con chúng ta
cũng sẽ có hai cách duyệt theo thứ tự nút gốc giữa:

Duyệt cây con trái, duyệt nút gốc, duyệt cây con phải
(Left – Root – Right)

Duyệt cây con phải, duyệt nút gốc, duyệt cây con trái
(Right – Root – Left)
ThS. Huỳnh Phước Danh Cấu trúc dữ liệu và giải thuật
- 11 -
DUYỆTCÂY NHỊ PHÂN
A
A
B
B
H
H
C
C
D
D
K
K
L
L
F
F
M
M
E

E
C, B, E, D, F, A, K, H, M, L
Thuật giải
void Traversal_LNR(BinT_Node* Root)
{
if (Root = = NULL) return;
Traversal_LNR(Root->left);
cout << Root->info << “ “;
Traversal_LNR(Root->right);
}
ThS. Huỳnh Phước Danh Cấu trúc dữ liệu và giải thuật
- 12 -
DUYỆTCÂY NHỊ PHÂN

Duyệt theo thứ tự nút gốc sau (Postorder):
Tương tự như duyệt theo nút gốc trước, trong cách duyệt
này thì nút gốc sẽ được duyệt sau cùng so với duyệt hai nút
gốc cây con. Do vậy, căn cứ vào thứ tự duyệt hai cây con mà
chúng ta cũng có hai cách duyệt theo thứ tự nút gốc sau:

Duyệt cây con trái, duyệt cây con phải, duyệt nút gốc
(Left – Right – Root)

Duyệt cây con phải, duyệt cây con trái, duyệt nút gốc
(Right – Left – Root)
ThS. Huỳnh Phước Danh Cấu trúc dữ liệu và giải thuật
- 13 -
DUYỆTCÂY NHỊ PHÂN
A
A

B
B
H
H
C
C
D
D
K
K
L
L
F
F
M
M
E
E
C, E, F, D, B, K, M, L, H, A
M, L, K, H, F, E , D , C, B
Thuật giải
void Traversal_LRN(BinT_Node* Root)
{
if (Root == NULL) return;
Traversal_LRN(Root->left);
Traversal_LRN(Root->right);
cout << Root->info << “ “;
}
ThS. Huỳnh Phước Danh Cấu trúc dữ liệu và giải thuật
- 14 -

CÂY TÌM KIẾM NHỊ PHÂN
Cây tìm kiếm nhị phân (TKNP) là cây nhị phân mà khoá
tại mỗi nút cây lớn hơn khoá của tất cả các nút thuộc cây con
bên trái và nhỏ hơn khoá của tất cả các nút thuộc cây con bên
phải.
Lưu ý: Dữ liệu lưu trữ tại mỗi nút có thể rất phức tạp như là
một record chẳng hạn, trong trường hợp này khoá của nút
được tính dựa trên một trường nào đó, ta gọi là trường khoá.
Trường khoá phải chứa các giá trị có thể so sánh được, tức là
nó phải lấy giá trị từ một tập hợp có thứ tự.
ThS. Huỳnh Phước Danh Cấu trúc dữ liệu và giải thuật
- 15 -
CÂY TÌM KIẾM NHỊ PHÂN
Ví dụ: hình minh hoạ một cây TKNP có khoá là số nguyên (với
quan hệ thứ tự trong tập số nguyên).
20
20
10
10
5
5
17
17
15
15
35
35
22
22
30

30
42
42
ThS. Huỳnh Phước Danh Cấu trúc dữ liệu và giải thuật
- 16 -
CÂY TÌM KIẾM NHỊ PHÂN
Qui ước: Cũng như tất cả các cấu trúc khác, ta coi cây rỗng là
cây TKNP
Nhận xét:

Trên cây TKNP không có hai nút cùng khoá.

Cây con của một cây TKNP là cây TKNP.

Khi duyệt trung tự (InOrder) cây TKNP ta được một dãy
có thứ tự tăng. Chẳng hạn duyệt duyệt cây con phải (Left –
Root - Right) cây trên ta có dãy: 5, 10, 15, 17, 20, 22, 30, 35,
42.
ThS. Huỳnh Phước Danh Cấu trúc dữ liệu và giải thuật
- 17 -
CÂY TÌM KIẾM NHỊ PHÂN
Cài đặt cây tìm kiếm nhị phân Cây TKNP, trước hết, là một
cây nhị phân. Do đó ta có thể áp dụng các cách cài đặt như
đã trình bày trong phần cây nhị phân. Sẽ không có sự khác
biệt nào trong việc cài đặt cấu trúc dữ liệu cho cây TKNP so
với cây nhị phân, nhưng tất nhiên, sẽ có sự khác biệt trong
các giải thuật thao tác trên cây TKNP như tìm kiếm, thêm
hoặc xoá một nút trên cây TKNP để luôn đảm bảo tính chất
cuả cây TKNP.
Tổ chức dữ liệu và khởi tạo

ThS. Huỳnh Phước Danh Cấu trúc dữ liệu và giải thuật
- 18 -
CÂY TÌM KIẾM NHỊ PHÂN
Tổ chức dữ liệu và khởi tạo
// Khai báo bi n root qu n lý cây nhi phan:ế ả
BinT_Node* Root;
//Kh i t o cây nhi phan: ở ạ
Root = NULL;
struct BinT_Node
{ <Kiểu dữ liệu> info;
BinT_Node *Left; // Vùng liên kết quản lý địa chỉ nút gốc cây con trái
BinT_Node *Right; // Vùng liên kết quản lý địa chỉ nút gốc cây con phải
};
ThS. Huỳnh Phước Danh Cấu trúc dữ liệu và giải thuật
- 19 -
CÂY TÌM KIẾM NHỊ PHÂN
Tìm kiếm một nút có khóa cho trước trên cây TKNP
Để tìm kiếm 1 nút có khoá x trên cây TKNP, ta tiến hành từ
nút gốc bằng cách so sánh khoá của nút gốc với khoá x.

Nếu nút gốc bằng NULL thì không có khoá x trên cây.

Nếu x bằng khoá của nút gốc thì giải thuật dừng và ta đã
tìm được nút chứa khoá x.

Nếu x lớn hơn khoá của nút gốc thì ta tiến hành (một
cách đệ qui) việc tìm khoá x trên cây con bên phải.

Nếu x nhỏ hơn khoá của nút gốc thì ta tiến hành (một
cách đệ qui) việc tìm khoá x trên cây con bên trái.

ThS. Huỳnh Phước Danh Cấu trúc dữ liệu và giải thuật
- 20 -
CÂY TÌM KIẾM NHỊ PHÂN
Ví dụ: tìm nút có khoá 30 trong cây ở bên

So sánh 30 với khoá nút gốc là 20, vì 30 >
20 vậy ta tìm tiếp trên cây con bên phải, tức
là cây có nút gốc có khoá là 35.

So sánh 30 với khoá của nút gốc là 35, vì
30 < 35 vậy ta tìm tiếp trên cây con bên trái,
tức là cây có nút gốc có khoá là 22.

So sánh 30 với khoá của nút gốc là 22, vì
30 > 22 vậy ta tìm tiếp trên cây con bên phải,
tức là cây có nút gốc có khoá là 30.

So sánh 30 với khoá nút gốc là 30, 30 = 30
vậy đến đây giải thuật dừng và ta tìm được
nút chứa khoá cần tìm.
20
20
10
10
5
5
17
17
15
15

35
35
22
22
30
30
42
42
ThS. Huỳnh Phước Danh Cấu trúc dữ liệu và giải thuật
- 21 -
CÂY TÌM KIẾM NHỊ PHÂN
BinT_Node* TreeSearch(int x, BinT_Node* Root)
{ if (Root == NULL)
return NULL; //không tìm thấy khoá x
else
if (Root->info == x) // tìm thấy khoá x
return Root;
else
if (Root->info < x) //tìm tiếp trên cây bên phải
return TreeSearch(x,Root->right);
return TreeSearch(x,Root->left);
}
Hàm dưới đây trả về kết quả là con trỏ trỏ tới nút chứa khoá
x hoặc NULL nếu không tìm thấy khoá x trên cây TKNP.
Tìm kiếm một nút có khóa cho trước trên cây TKNP
ThS. Huỳnh Phước Danh Cấu trúc dữ liệu và giải thuật
- 22 -
CÂY TÌM KIẾM NHỊ PHÂN
Thêm một nút có khóa cho trước vào cây TKNP
Theo định nghĩa cây tìm kiếm nhị phân ta thấy trên cây tìm

kiếm nhị phân không có hai nút có cùng một khoá. Do đó nếu
ta muốn thêm một nút có khoá x vào cây TKNP thì trước hết
ta phải tìm kiếm để xác định có nút nào chứa khoá x chưa.
Nếu có thì giải thuật kết thúc (không làm gì cả!). Ngược lại, sẽ
thêm một nút mới chứa khoá x này.
Việc thêm một khoá vào cây TKNP là việc tìm kiếm và thêm
một nút, tất nhiên, phải đảm bảo cấu trúc cây TKNP không bị
phá vỡ. Giải thuật cụ thể như sau:
ThS. Huỳnh Phước Danh Cấu trúc dữ liệu và giải thuật
- 23 -
CÂY TÌM KIẾM NHỊ PHÂN
Thêm một nút có khóa cho trước vào cây TKNP
Ta tiến hành từ nút gốc bằng cách so sánh khóa cuả nút gốc
với khoá x.

Nếu nút gốc bằng NULL thì khoá x chưa có trên cây, do
đó ta thêm một nút mới chứa khoá x.

Nếu x bằng khoá của nút gốc thì giải thuật dừng, trường
hợp này ta không thêm nút.

Nếu x lớn hơn khoá của nút gốc thì ta tiến hành (một
cách đệ qui) giải thuật này trên cây con bên phải.

Nếu x nhỏ hơn khoá của nút gốc thì ta tiến hành (một
cách đệ qui) giải thuật này trên cây con bên trái.
ThS. Huỳnh Phước Danh Cấu trúc dữ liệu và giải thuật
- 24 -
CÂY TÌM KIẾM NHỊ PHÂN
Thêm một nút có khóa cho trước vào cây TKNP

Ví dụ: thêm khoá 19 vào cây

So sánh 19 với khoá của nút gốc là 20, vì 19 < 20
vậy ta xét tiếp đến cây bên trái, tức là cây có nút
gốc có khoá là10.

So sánh 19 với khoá của nút gốc là 10, vì 19 > 10
vậy ta xét tiếp đến cây bên phải, tức là cây có nút
gốc có khoá là 17.

So sánh 19 với khoá của nút gốc là 17, vì 19 > 17
vậy ta xét tiếp đến cây bên phải. Nút con bên phải
bằng NULL, chứng tỏ rằng khoá 19 chưa có trên
cây, ta thêm nút mới chứa khoá 19 và nút mới này
là con bên phải của nút có khoá là 17
20
20
10
10
5
5
17
17
15
15
35
35
22
22
30

30
42
42
19
19
ThS. Huỳnh Phước Danh Cấu trúc dữ liệu và giải thuật
CÂY TÌM KIẾM NHỊ PHÂN
Thêm một nút có khóa cho trước vào cây TKNP
Thủ tục sau đây tiến hành việc thêm một khoá vào cây TKNP.
void InsertNode(int x, BinT_Node* &Root )
{ if (Root == NULL)
{ /* thêm nút mới chứa khoá x */
Root=new BinT_Node();
Root->info= x;
Root->left = NULL;
Root->right = NULL;
} else
if (x < Root->Key) InsertNode(x , Root->left);
else
if (x > Root->Key) InsertNode(x , Root->right);
}

×