You are on page 1of 41

TRƯỜNG ĐẠI HỌC NGÂN HÀNG TP HCM

KHOA HỆ THỐNG THÔNG TIN QUẢN LÝ

Chương 7

Tìm kiếm
1
Khoa Hệ Thống Thông Tin Quản lý

Nội dung

❖Khái niệm và vai trò của việc tìm kiếm dữ liệu


❖Một số giải thuật tìm kiếm phổ biến
✓ Tìm kiếm Tuyến Tính
✓ Tìm kiếm Nhị Phân
❖Minh họa thuật toán
❖Đánh giá độ phức tạp của thuật toán

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 2


Khoa Hệ Thống Thông Tin Quản lý

Đặt vấn đề

Minion
răng sún
đâu rồi nhỉ

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 3


Khoa Hệ Thống Thông Tin Quản lý

Đặt vấn đề
Oh My God!
Đồ đạc tùm lum
thế này làm sao
tìm thấy chìa khóa

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 4


Khoa Hệ Thống Thông Tin Quản lý

Đặt vấn đề
Số 6 ở
đâu nhỉ?

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 5


Khoa Hệ Thống Thông Tin Quản lý

Khái niệm

✓Tìm kiếm là việc ta muốn lọc ra một hay một


số đối tượng (phần tử) “có những đặc tính
nào đó” từ một tập dữ liệu có trước để xử lý.
Dữ liệu bên trong để Tìm kiếm
không theo thứ tự tuần tự

Tập dữ liệu Tìm kiếm


có trước tuần tự
Dữ liệu bên trong để
có theo thứ tự
Tìm kiếm
Nhị phân

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 6


Khoa Hệ Thống Thông Tin Quản lý

Một số giải thuật Tìm kiếm phổ biến

✓Đơn giản hóa bài toán:


Để đơn giản hoá bài toán và cho việc biểu diễn
thuật toán dễ dàng mà không làm mất tính tổng
quát, xem như:
* Dữ liệu cho tìm kiếm là một mảng các số nguyên
* Dữ liệu tìm kiếm : (khoá) giá trị số nguyên
M[0] M[1] M[2] M[…] M[N-2] M[N-1]

15 22 9 … 100 30

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 7


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính

Xét phần tử từ đầu cho đến cuối một cách tuần tự


Tại vị trí thứ i:
Nếu giá trị trong dữ liệu đúng với khoá cần tìm kiếm
-> tìm thấy
Nếu không đúng tìm đến phần tử kế tiếp i+1
Nếu sau khi xét hết N phần tử mà không có giá trị
khoá cần tìm → không tìm thấy

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 8


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính

Mã giả:
➢ Bước 1: i = 0 ➔ bắt đầu từ phần tử đầu tiên của dãy
➢ Bước 2: So sánh M[i] với x, có 2 khả năng :
+ M[i] = x : Tìm thấy. Dừng
+ M[i] ≠ x : Sang Bước 3.
➢ Bước 3 : i = i+1➔ xét tiếp phần tử kế trong mảng
Nếu i >=N: Hết mảng, không tìm thấy. Dừng
Ngược lại: Lặp lại Bước 2.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 9


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính

Cài đặt giải thuật:

for (i=0;i<N;i++)
{
if(M[i]==x)
printf (“tìm thấy tại vị trí %d”,i);
}
if (i>=N)
printf (“không tìm thấy”);
(với x là biến khoá nhập vào cho tìm kiếm )

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 10


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính

➢ Ví dụ: Cho dãy số M


25 20 9 5 7 4 13 17
➢ Giá trị cần tìm: x= 9

i=0
X=9

25 20 9 5 7 4 13 17

0 1 2 3 4 5 6 7

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 11


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính

i=1
X=9

25 20 9 5 7 4 13 17

0 1 2 3 4 5 6 7

i=2
X=9

25 20 9 5 7 4 13 17

0 1 2 3 4 5 6 7

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 12


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính

Int M[] = { 25,20,9,5,7,4,13,17 };

int LinearSearch(int M,int x, int n)


{
int i;
for (i = 0; (i < n) && (M[i] != x); i++);
if (i == n)
return -1;// tìm hết mảng nhưng không có x
else
return i; // M[i] là phần tử có khoá x
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 13


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính

Int M[]= { 25,20,9,5,7,4,13,17 };

int LinearSearch(int M[], int x, int n)


{
int i;
for (i = 0; i < n; i++)
{
if(M[i] == x)
return i; // M[i] là phần tử có khoá x
}
return -1;// tìm hết mảng nhưng không có x
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 14


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính

Int M[] = { 25,20,9,5,7,4,13,17 };

int LinearSearch(int M, int x, int n)


{
int tam = -1;
for (int i = 0; i < n; i++)
{
if(M[i] == x) tam = i; // M[i] là phần tử có khoá x
}
return tam;//tam=-1 nếu tìm hết mảng nhưng không có x
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 15


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính

Cải tiến cài đặt: dùng phương pháp “lính canh”


• Đặt thêm một phần tử có giá trị x vào cuối mảng
• Bảo đảm luôn tìm thấy x trong mảng
• Sau đó dựa vào vị trí tìm thấy để kết luận.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 16


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính


int LinearSearch(int x){
// mảng gồm N phần tử từ M[0]..M[N-1]
M[N] = x; // thêm phần tử thứ N+1
for ( i=0; (M[i]!=x );i++);
if (i==N)
return -1; // tìm hết mảng nhưng không có x
else
return i; // tìm thấy x tại vị trí i
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 17


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính

Ðánh giá giải thuật


Trường hợp Số lần so Giải thích
sánh
Tốt nhất 1 Phần tử đầu tiên có giá trị k
Xấu nhất n+1 Phần tử cuối cùng có giá trị k
Trung bình (n+1)/2 Giả sử xác suất các phần tử trong
mảng nhận giá trị x là như nhau.

Vậy giải thuật tìm tuyến tính có độ phức tạp tính toán
cấp n: T(N) = O(N)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 18


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính

➢ Nhận xét:
✓ Giải thuật tìm tuyến tính không phụ thuộc vào thứ tự
của các phần tử mảng, do vậy đây là phương pháp
tổng quát nhất để tìm kiếm trên một dãy bất kỳ.
✓ Một Giải thuật có thể được cài đặt theo nhiều cách
khác nhau, kỹ thuật cài đặt ảnh hưởng đến tốc độ
thực hiện của giải thuật.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 19


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính

❖ Cải tiến giải thuật


Giải Thuật tìm kiếm tuyến tính cải tiến:
Chỉ xét tìm kiếm giá trị x đến phần tử thứ m trong dữ
liệu với x còn nhỏ hơn Mm
while ((x<=M[i])&&(i<=N) i++;
if(M[i]==x) printf(“tìm thấy tại %d”,i);
else printf(‘không tìm thấy ’);
(với x là biến khoá nhập vào cho tìm kiếm )

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 20


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính

❖ Bài tập: Cho danh sách sản phẩm gồm các thông
tin: Mã, tên, đơn giá. Hãy mô hình hóa dữ liệu và
viết các giải thuật tìm kiếm Tuần tự:
✓ Tìm sản phẩm có mã X
✓ Tìm các sản phẩm có đơn giá [A…B]
✓ Tìm các sản phẩm mà phần tên có chứa Z

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 21


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân


❖ Đặc trưng Dữ liệu: Đã được sắp xếp theo một thứ tự
nào đó (nhỏ→ lớn)
❖ Tính chất của dữ liệu được sắp là :
Mi-1<= Mi<=Mi+1
➔Vậy nếu x> Mi thì x chỉ có thể xuất hiện trong đoạn
[Mi+1 ,MN-1] của dãy, ngược lại nếu x< Mi thì x chỉ có
thể xuất hiện trong đoạn [M0 ,Mi-1] của dãy
❖ Giải thuật tìm nhị phân áp dụng nhận xét trên đây với
tư tưởng chia để trị để tìm cách giới hạn phạm vi tìm
kiếm sau mỗi lần so sánh x với một phần tử trong dãy.
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 22
Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân

Mi-1 Mi Mi+1

Mi>x Mi<x

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 23


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân


❖ Cài đặt giải thuật:
Bước 1: left = 0; right = N-1; // tìm kiếm trên tất cả các phần tử
Bước 2:
mid = (left+right)/2; // lấy mốc so sánh
So sánh M[mid] với k, có 3 khả năng :
M[mid] = k: Tìm thấy. Dừng
M[mid] > k: Tìm tiếp x trong dãy con M[left] .. M[mid -1] :
right =mid - 1;
M[mid] < k: Tìm tiếp x trong dãy con M[mid +1] .. M[right] :
left = mid + 1;
Bước 3:
Nếu left <= right : Còn phần tử chưa xét → tìm tiếp.
Lặp lại Bước 2.
Ngược lại: Dừng; //Ðã xét hết tất cả các phần tử, không tìm thấy.
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 24
Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân


❖ Cài đặt giải thuật:
int BinarySearch(int M[],int n, int x)
{
int left = 0, right = n-1;
int mid;
do
{
mid = (left + right) / 2;
if (x == M[mid])
return mid;//Thấy x tại mid
else if (x < M[mid])
right = mid - 1;
else
left = mid + 1;
} while (left <= right);
return -1; // Tìm hết dãy mà không có x
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 25


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân ❖ Ví dụ minh họa 1

int M[] = {1, 5, 15, 19, 25, 27, 29, 31,33,45,55,88,100};

int kq= BinarySearch(M,13, 19);

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 26


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân ❖ Ví dụ minh họa 1


M
Tìm phần tử X = 19
0 1
1 5
2 15
3 19
4 25
5 27
Middle=(0+12)/2=6
6 29
M[6]=29 > x= 19
7 31
➔Ta tìm phần nửa nhỏ hơn còn lại của M
8 33
(tức là từ 0→5)
9 45
10 55
11 88
12 100
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 27
Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân ❖ Ví dụ minh họa 1


M
Tìm phần tử X = 19
0 1
1 5
2 15 Middle=(0+5)/2=2
3 19 M[2]=15 < x= 19
4 25
5 27 ➔Ta tìm phần nửa lớn hơn còn lại của M
(tức là từ 3→5)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 28


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân ❖ Ví dụ minh họa 1

Tìm phần tử X = 19
M

3 19
Middle=(3+5)/2=4
4 25 M[4]=25 > x= 19
5 27
➔Ta tìm phần nửa nhỏ hơn còn lại của M
(tức là từ 3→3)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 29


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân ❖ Ví dụ minh họa 1

Tìm phần tử X = 19
M

19 Middle=(3+3)/2=3
3
M[3]=19 = x =19
Tìm thấy X=19 ở vị trí thứ 3

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 30


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân ❖ Ví dụ minh họa 2

int[] M = { 1, 5, 15, 19, 25, 27, 29, 31,33,45,55,88,100};

int kq= BinarySearch(M,13, 18);

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 31


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân ❖ Ví dụ minh họa 2


M
Tìm X = 18
0 1
1 5
2 15
3 19
4 25
5 27
6 29 Middle=(0+12)/2=6
7 31 M[6]=29 > x= 18
8 33 ➔Ta tìm phần nửa nhỏ hơn còn lại của M
9 45 (tức là từ 0→5)
10 55
11 88
12 100
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 32
Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân ❖ Ví dụ minh họa 2


M
Tìm X = 18
0 1
1 5
2 15 Middle=(0+5)/2=2
3 19 M[2]=15 < x= 18
4 ➔Ta tìm phần nửa lớn hơn còn lại của M
25
5 (tức là từ 3→5)
27

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 33


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân ❖ Ví dụ minh họa 2

Tìm X = 18
M

3 19
4 Middle=(3+5)/2=4
25
5 M[4]=25 > x= 18
27
➔Ta tìm phần nửa nhỏ hơn còn lại của M
(tức là từ 3→3)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 34


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân ❖ Ví dụ minh họa 2

Tìm X = 18
M

3 19 Middle=(3+3)/2=3
M[3]=19 > x= 18
➔không còn phần tử nào để so sánh.

Không tim thấy x=18

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 35


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân ❖ Ví dụ minh họa 3

int[] M = { 18, 5, 25, 10, 22, 3, 29};

int kq=BinarySearch(M,7 25);


Nhận xét dữ liệu có vấn đề gì không?

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 36


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân


❖ Đánh giá giải thuật
Trường Số lần Giải thích
hợp so sánh
Tốt nhất 1 Phần tử giữa của mảng có giá trị x
Xấu nhất log 2 n Không có x trong mảng
Trung bình log 2 n/2 Giả sử xác suất các phần tử trong
mảng nhận giá trị x là như nhau

Vậy giải thuật tìm Nhị Phân có độ phức tạp tính toán cấp n:
T(N) = O(log 2 N)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 37


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân


❖ Nhận xét
➢ Giải thuật tìm nhị phân dựa vào quan hệ giá trị của
các phần tử mảng để định hướng trong quá trình tìm
kiếm, do vậy chỉ áp dụng được cho những dãy đã có
thứ tự.
➢ Giải thuật tìm nhị phân tiết kiệm thời gian hơn rất
nhiều so với giải thuật tìm tuyến tính do
➢ Tnhị phân (N) = O(log 2 N) < Ttuyến tính (N) = O(N).

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 38


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân


❖ Nhận xét
➢ Khi muốn áp dụng giải thuật tìm nhị phân cần phải xét
đến thời gian sắp xếp dãy số để thỏa điều kiện dãy số có
thứ tự. Thời gian này không nhỏ, và khi dãy số biến động
cần phải tiến hành sắp xếp lại => khuyết điểm chính cho
giải thuật tìm nhị phân.
➢ Cần cân nhắc nhu cầu thực tế để chọn một trong hai giải
thuật tìm kiếm trên sao cho có lợi nhất
➢ Thường xuyên biến động, ít tìm kiếm → tuần tuyến tính
➢ Ít biến động, tần suất tìm kiếm nhiều → nhị phân

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 39


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân


❖ Mở rộng: Cài đặt bằng Đệ qui
➢ Phát hiện: Phần cơ sở khi left>Right hoặc tìm thấy,
phần đệ qui là lặp lại quá trình chia danh sách

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 40


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân

int[] M = { 1, 5, 15, 19, 25, 27, 29, 31,33,45,55,88,100};

MessageBox.Show("" + BinarySearch(M, 27, 0, M.Length-1));

int BinarySearch(int []M, int x, int left, int right)


{
if (left > right)
return -1;
int mid = (left + right) / 2;
if (x == M[mid])
return mid;
if (x < M[mid])
return BinarySearch(M, x, left, mid - 1);
return BinarySearch(M, x, mid + 1, right);
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 41

You might also like