You are on page 1of 22

Chương 7

Tìm kiếm

LOGO
Nội dung

 Bài toán tìm kiếm

 Tìm kiếm tuần tự

 Tìm kiếm nhị phân

 Cây nhị phân tìm kiếm


Bài toán tìm kiếm

Cho biết:

 Một danh sách các bản ghi (record).

 Một khóa cần tìm.

Tìm bản ghi có khóa trùng với khóa cần


tìm (nếu có).

Đo độ hiệu quả:

 Số lần so sánh khóa cần tìm và khóa bản ghi


Khóa và bản ghi

Bản ghi:
 Khóa
 Dữ liệu
Khóa:
 So sánh được
 Thường là số
Bài toán tìm kiếm
Tham số vào:
 Danh sách cần tìm
 Khóa cần tìm
Tham số ra:
 Vị trí phần tử tìm thấy (nếu có)
Tìm kiếm tuần tự
Tìm kiếm tuần tự
Tìm kiếm tuần tự
Giải thuật:
sequential_search(K,n,x)
{
for(i=0; i<n; i++)
if(K[i]==x) return i;
return -1;
}
Số lần so sánh trên khóa
 Tìm không thành công: n.
 Tìm thành công, trường hợp tốt nhất: 1.
 Tìm thành công, trường hợp xấu nhất: n.
 Tìm thành công, trung bình: (n + 1)/2.
Tìm kiếm nhị phân

Ý tưởng:
 Dãy đã được sắp xếp
 So sánh khóa cần tìm với phần tử giữa.
 Nếu nó nhỏ hơn thì tìm bên trái danh sách.
 Ngược lại tìm bên phải danh sách.
 Lặp lại động tác này.
Cần 2 chỉ mục top và bottom để giới hạn
đoạn tìm kiếm trên danh sách.
Khóa cần tìm nếu có chỉ nằm trong đoạn
này.
Tìm kiếm nhị phân
Tìm kiếm nhị phân

Giải thuật:
Binary_Search(K, t, p, x) {
if (t > p) return -1; // Không tìm thấy
else {
g = (t+p) / 2;
if (x == K[g]) return g; // Tìm thấy
if (x < K[g])
Binary_Search(K, t, g - 1, x) // Tìm tiếp ở nửa trước
else
Binary_Search(K, g + 1, p, x) // Tìm tiếp ở nửa sau
}
}
Tìm kiếm nhị phân
Số lần so sánh trên khóa
 Tìm thành công, trường hợp tốt nhất: 1.
 Tìm thành công, trường hợp xấu nhất: log2n .
 Tìm thành công, trung bình: log2n.
Cây nhị phân tìm kiếm
Một cây nhị phân tìm kiếm là một cây nhị
phân mà mỗi node của cây này có các đặc
tính sau:
 1. Khóa của node gốc lớn hơn khóa của tất
cả các node của cây con bên trái
 2. Khóa của node gốc nhỏ hơn khóa của tất
cả các node của cây con bên phải
Cây nhị phân tìm kiếm

 Giải thuật:
Chọn hướng tìm theo tính chất của cây nhị
phân tìm kiếm:
 So sánh với node gốc, nếu đúng thì tìm thấy
 Tìm bên nhánh trái (hay phải) nếu khóa cần
tìm nhỏ hơn (hay lớn hơn) khóa của node gốc
Giống phương pháp tìm kiếm nhị phân
Thời gian tìm kiếm
 Tốt nhất và trung bình: O(logn)
 Tệ nhất: O(n)
Cây nhị phân tìm kiếm
Giải thuật P = P->P_R;
}
BTS(T, x, Q) {/* khoá tìm kiếm là
x. Nếu tìm kiếm thành công thì cho con
P = malloc();
trỏ P trỏ tới nút đó, nếu tìm kiếm //x chưa có, thực hiện bổ sung
không thành công thì bổ sung nút mới P->KEY = x;
có khoá là x vào T và cho con trỏ P trỏ
vào nút mới đó kèm theo thông báo */
P->P_L = P->P_R = NULL;
Q = NULL; P = T; if (T == NULL)
//Cây rỗng, nút mới chính là gốc
while (P!=NULL) //Tìm kiếm,
con trỏ Q trỏ vào nút cha của P T = P;
{ else
if ( x == P->KEY) if ( x < Q->KEY)
return ; Q->P_L = P;
Q = P; else
if (x < P->KEY) Q->P_R = P;
P = P->P_L; printf(“Không tìm thấy, đã
else bổ sung”)
Xóa một node trên cây nhị
phân tìm kiếm
Xóa node lá:cho mối nối trỏ tới node cần
xóa (từ nút cha) trỏ về NULL, rồi giải
phóng node đó
Xóa node chỉ có 1 nhánh con: Cho mối nối
trỏ tới node đó (từ nút cha) trỏ vào nút
gốc nhánh con của nó. Sau đó giải phóng
node đó.
Xóa một node trên cây nhị
phân tìm kiếm
 Xóa nút có đủ 2 nhánh con:
nút thay thế là nút lớn nhất
thuộc cây con trái (nút cực
phải của cây con trái) hoặc là
nút nhỏ nhất thuộc cây con
phải (nút cực trái của cây con
phải) của nút đó, lấy giá trị
của nút “thay thế” thay cho
giá trị của nút đó, rồi xóa nút
“thay thế”. Vì đặc điểm của
nút “thay thế” nên nó chỉ có
thể là nút có một nhánh con
hoặc là nút lá, do vậy việc
xóa nó giống như hai trường
hợp đầu.
Xóa node trên cây nhị phân
tìm kiếm
BST_Delete(T, x) { while (P->P_R != NULL){
P=T;Q=NULL;//Q luôn là cha của P Q = P; P = P->P_R;
while (P!=NULL) { //Tìm x trên cây }
if(P->Key==x) //Tìm thấy // Chuyển giá trị trong nút thay thế lên
break ; Node->KEY = P->KEY;
Q = P; }
if ( x < P->KEY) if (P->P_L != NULL)
P = P->P_L Child = P->P_L;
else else
P = P->P_R; Child = P->P_R;
} if (P == T) //nút bịxoá là nút gốc
if(P==NULL) //x không có trên cây T = Child;
return; else // Sửa mối nối cũ trỏ vào P
if(P->P_L!=NULL&&P->P_R!=NULL) thành trỏ vào Child
//P có đủ hai cây con if (Q->P_L == P)
{ //sẽ tìm nút cực phải của cây con trái Q->P_L = Child;
làm nút thay thế
else
Node = P; //Ghi nhớ nút cần xoá Q->P_R = Child;
//tìm nút “thay thế” và cho P trỏ vào
free(P); // Giải phóng P
Q = P; P = P->P_L; }
Q&A
Bài tập áp dụng
1. Cho dãy số nguyên sau: 3 5 7 9 10 12 15 20
a. Mô tả các bước hoạt động của giải thuật tìm kiếm tuần
tự để tìm x=10.
b. Mô tả các bước hoạt động của giải thuật tìm kiếm nhị
phân để tìm x=13.
2. Cho dãy các số nguyên sau: 55 60 15 25 45
40 50 20 10 30
a. Áp dụng giải thuật tìm kiếm có bổ sung trên cây nhị
phân tìm kiếm, hãy dựng cây nhị phân tìm kiếm khi
thêm tuần tự dãy số trên vào cây rỗng ban đầu.
b. Hãy biểu diễn hình ảnh của cây từ câu a) khi xoá nút
có khoá 50 và 15.
c. Mô tả quá trình tìm x=30 trên cây đã xây dựng.
Bài tập áp dụng
3. Từ ý tưởng của giải thuật tìm kiếm nhị phân,
người ta đưa ra ý tưởng cho giải thuật tìm
kiếm tam phân như sau: chia dãy ban đầu [K0,
K1, ..., Kn-1] thành ba dãy con tại các vị trí
Km1, Km2. Lần lượt so sánh x với hai phần tử
đó, nếu x không bằng một trong hai phần tử
đó, thì giới hạn tiếp vùng tìm kiếm là dãy [K0,
K1, ..., Km1-1], hay dãy [Km1+1, ..., Km2-1],
hoặc dãy [Km2+1, ..., Kn-1]
a. Viết giải thuật tìm kiếm tam phân.
b. Hãy xác định độ phức tạp tính toán của giải
thuật
c. Lấy ví dụ minh họa hoạt động của giải thuật.
Bài tập áp dụng
4. Viết chương trình thực hiện các yêu cầu
sau:
a. Nhập vào dãy khóa là các số nguyên khác
nhau và lưu trữ dưới dạng cấu trúc cây nhị
phân tìm kiếm.
b. Viết hàm tìm kiếm một khóa x trên cây.
c. Viết hàm xóa một nút trên cây.
d. Viết hàm in giá trị nhỏ nhất, lớn nhất trên cây.
e. Viết hàm in dãy khóa theo chiều tăng dần.

You might also like