Chương 5. Cây nhị phân tìm kiếm
Trần Minh Thái
Email:
Website: www.minhthai.edu.vn
1
Nội dung
1.
2.
3.
4.
5.
Khái niệm
Đặc điểm
Định nghĩa cấu trúc dữ liệu
Các lưu ý khi cài đặt
Các thao tác xử lý
2
Khái niệm
Bậc của một nút: là số cây con của nút đó
Bậc của cây: 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
2
2
2
0
1
1
0
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
0
0
3
Khái niệm
Chiều dài đường đi đến nút x: là
số nhánh cần đi qua kể từ gốc
đến x
Mức 1
Chiều cao h của cây: Mức lớn
nhất của các nút lá
Mức 2
Mức 3
Mức 4
xx
4
Đặc điểm của cây nhị phân
Số nút ở mức I ≤ 2I-1
Số nút ở mức lá ≤ 2h-1, với h là chiều cao của cây
Chiều cao của cây h ≥ log2N, với N là số nút trong cây
5
Biểu diễn cây nhị phân
Cây nhị phân là một cấu trúc bao gồm các phần tử (node) được kết nối với
nhau theo quan hệ “cha-con” với mỗi cha có tối đa 2 con.
Mỗi nút gồm các thông tin:
Dữ liệu lưu trữ: data
Liên kết tới cây con trái của nút: pLeft
Liên kết tới cây con phải của nút: pRight
6
Định nghĩa kiểu dữ liệu dùng C
data
Giá trị
TNODE
Nút
Trỏ trái
pLeft
Trỏ phải
typedef struct TNode
{
DataType data;
TNode *pLeft, *pRight;
} *Tree;
7
pRight
Ví dụ khai báo node chứa giá trị nguyên
typedef struct TNode
{
int data;
TNode *pLeft, *pRight;
} *Tree;
8
Cây nhị phân tìm kiếm
Là 1 cây nhị phân
Giá trị của một node luôn lớn hơn giá trị của các
node nhánh trái và nhỏ hơn giá trị các node nhánh
77
phải
Nút có giá trị nhỏ nhất nằm ở nút trái nhất của cây
33
36
36
11
66
44
15
15
Nút có giá trị lớn nhất nằm ở nút phải nhất của cây
40
40
23
23
9
Các lưu ý khi cài đặt
Bước 1: Khai báo kiểu dữ liệu biểu diễn cây
Bước 2: Xây dựng hàm đưa dữ liệu (nhập) vào cây
Bước 3: Xây dựng các thao tác duyệt, tìm kiếm, huỷ, …
10
Cấu trúc chương trình
Khai báo cấu trúc cây
Khởi tạo cây rỗng
Xây dựng cây
Các thao tác
Hủy cây
11
Các thao tác cơ bản
1. Tạo cây
2. Duyệt cây
3. Cho biết các thơng tin của cây
4. Tìm kiếm
5. Xố node trên cây
12
Tạo cây
7
36
3
7643136
15
40
3136
764
40
15
1
6
4
15
40
Nếu node cần thêm nhỏ hơn node
đang xét thì thêm về bên trái
Ngược lại thì thêm về bên phải
13
Hàm thêm một phần tử vào cây
int InsertNode (Tree & t, int x)
{
if(t!=NULL)
{
if(x==t->data)
return 0; //Có giá trị trùng
else
{
if(x<t->data)
else
InsertNode(t->pLeft, x);
InsertNode(t->pRight, x);
}
}
else
{
t=new TNode;
if(t==NULL)
return -1; //Thiếu bộ nhớ
t->data=x;
t->pLeft=t->pRight=NULL;
return 1; //Thêm thành công
}
}
14
Bài tập
1.
Viết hàm tạo cây nhị phân số nguyên từ các giá trị nhập vào từ bàn phím.
Q trình nhập cho đến khi gặp giá trị trùng hoặc hết bộ nhớ
2.
Viết hàm tạo cây nhị phân số nguyên từ dãy số nguyên cho trước
15
Duyệt cây
Thứ tự trước
(NLR)
Thứ tự giữa
(LNR)
Thứ tự sau
(LRN)
16
77
Bước
1
Kết quả duyệt theo thứ tự NLR
7
2
L7
R7
3
L3
3
1
4
33
R3
R7
R3
R7
6
L6
5
36
36
4
6
11
66
15
15
R7
44
R7
36
7
23
23
L36
R36
15
R15
R36
23
R36
8
9
KQ
40
40
40
7
3
1
6
4
36
15
23
17
40
Hàm duyệt NLR
Tại node t đang xét, nếu khác rỗng thì
In giá trị của t
Duyệt cây con bên trái của t theo thứ tự
void NLR (Tree t)
{
if(t!=NULL)
NLR
{
Duyệt cây con bên phải của t theo thứ tự
cout<<t->Key<<“\t”;
NLR
NLR(t->pLeft);
NLR(t->pRight);
}
}
18
Bài tập
Vẽ cây nhị phân tìm kiếm theo thứ tự nhập từ trái sang phải và duyệt cây theo
thứ tự trước:
27; 19; 10; 21; 35; 25; 41; 12; 46; 7
H; B; C; A; E; D; Z; M; P; T
Huế; Đà Nẵng; Hà Nội; Vĩnh Long; Cần Thơ; Sóc Trăng; Nha Trang; Đồng
Nai; Vũng Tàu; An Giang; Tiền Giang; Bình Dương; Hải Dương
19
Bước
Kết quả duyệt theo thứ tự LNR
77
1
L7
7
R7
2
L3
3
R3
7
R7
3
1
3
R3
7
R7
3
R3
7
R7
5
L6
6
7
R7
6
4
6
7
R7
6
7
R7
7
R7
4
7
8
33
36
36
11
66
15
15
44
23
23
9
L36
36
R36
10
15
R15
36
R36
23
36
R36
36
R36
11
12
13
KQ
40
1
3
4
6
7
15
23
36
20
40
40
40
Hàm duyệt LNR
Tại node t đang xét, nếu khác rỗng thì
void LNR (Tree t)
{
Duyệt cây con bên trái của t theo thứ tự
if(t!=NULL)
{
LNR
LNR(t->pLeft);
In giá trị của t
Duyệt cây con bên phải của t theo thứ
cout<<t->Key<<“ “;
LNR(t->pRight);
}
tự LNR
}
21
Bước
Kết quả duyệt theo thứ tự LRN
77
1
L7
R7
7
2
L3
R3
3
R7
7
3
1
R3
3
R7
7
4
L6
6
3
R7
7
5
4
6
3
R7
7
6
3
R7
7
3
R7
7
8
L36
R36
36
7
9
R15
15
R36
36
7
10
23
15
R36
36
7
15
R36
36
7
40
36
7
36
7
6
7
11
33
12
36
36
11
66
44
13
14
KQ
15
15
23
23
7
1
4
6
3
23
15
40
36
22
40
40
7
Hàm duyệt LRN
Tại node t đang xét, nếu khác rỗng thì
Duyệt cây con bên trái của t theo thứ tự LRN
Duyệt cây con bên phải của t theo thứ tự LRN
In giá trị của t
void LRN (Tree t)
{
if(t!=NULL)
{
LRN(t->pLeft);
LRN(t->pRight);
cout<<t->Key<<“ “;
}
}
23
Bài tập
Vẽ cây nhị phân tìm kiếm theo thứ tự nhập:
27, 19, 10, 21, 3, 15, 41, 50, 30, 7
Hãy duyệt cây trên theo thứ tự giữa
Vẽ cây nhị phân tìm kiếm theo thứ tự nhập:
H, B, C, A, E, D, T, M, X, O
Hãy duyệt cây trên theo thứ tự sau
24
Kiểm tra kết quả duyệt bằng cách xây dựng lại cây nhị phân từ kết
quả duyệt
Tạo cây từ kết quả duyệt NLR
Chọn giá trị đầu tiên làm node gốc
Lần lượt đưa các giá trị còn lại từ trái sang phải vào cây theo nguyên tắc tạo
cây
Tạo cây từ kết quả duyệt LRN
Chọn giá trị cuối cùng làm node gốc
Lần lượt đưa các giá trị còn lại từ phải sang trái vào cây theo nguyên tắc tạo
cây
25