Chương 2.1. Giải thuật tìm kiếm
Trần Minh Thái
Email:
Website: www.minhthai.edu.vn
1
Mục tiêu
Xác định được vai trị của tìm kiếm và sắp xếp trong hệ thống thông tin
Nắm vững và minh họa được giải thuật tìm tuần tự và tìm kiếm nhị phân trên
mảng một chiều
Cài đặt được giải thuật tìm kiếm bằng ngôn ngữ C
2
Nhu cầu tìm kiếm và sắp xếp
Tìm kiếm: Có trong hầu hết trong các hệ thống thơng tin
Muốn tìm kiếm nhanh và hiệu quả dữ liệu có thứ tự sắp xếp
3
Vấn đề tìm kiếm
Dựa vào một phần thơng tin được gọi là khố (key) tìm một mẫu tin (record)
chứa các thơng tin khác liên quan với khố này
Có thể có nhiều mẫu tin hoặc khơng có mẫu tin nào chứa khố cần tìm
4
Đánh giá giải thuật tìm kiếm
Tìm kiếm thường là tác vụ tốn nhiều thời gian trong một chương trình
Tổ chức cấu trúc dữ liệu và giải thuật cho việc tìm kiếm ảnh hưởng lớn đến
hiệu suất hoạt động của chương trình
Thơng số đo chủ yếu là số lần so sánh khố cần tìm với các mẫu tin khác
5
Phân loại
Tìm kiếm nội và tìm kiếm ngoại
Dữ liệu lưu trên thiết bị lưu trữ ngoài như đĩa hay băng từ: tìm kiếm ngoại
Dữ liệu được lưu trữ trên bộ nhớ chính: tìm kiếm nội
6
Các giải thuật tìm kiếm
Có 2 giải thuật thường được áp dụng: tìm tuần tự và tìm nhị phân
Đặc tả:
trữ alà dãy sốa gồm N phần tử a0…, a1, ... ,an-1 a
Tập
a0 dữ liệu
a1 đượcalưu
2
3
4
n-2
Khai báo: int a[n];
Khóa cần tìm: int x;
7
an-1
Tìm tuần tự (Linear Search)
Ý tưởng
Lần lượt so sánh x với phần tử thứ nhất, thứ hai, ... của mảng a cho đến khi gặp được
phần tử cần tìm, hoặc hết mảng
8
Tìm tuần tự
Minh họa tìm x =10
10
Đã tìm
thấy
Chưa
hếttại
7
5
12
41
10
10
32
13
9
15
3
0
1
2
3
4
5
6
7
8
9
Minh họa tìm x =25
25
vịmảng
trí 4
Chưa hết mảng
Đã hết mảng
7
5
12
41
10
32
13
9
15
3
0
1
2
3
4
5
6
7
8
9
9
Giải thuật
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 a[i] với x, có 2 khả năng :
a[i] = x : Tìm thấy. Dừng
a[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-1: Hết mảng, khơng tìm thấy. Dừng
Ngược lại: Lặp lại Bước 2.
10
Ngun tắc cài đặt hàm tìm kiếm
Nếu có xuất hiện phần tử có giá trị x thì trả về vị trí tìm được
Ngược lại thì trả về -1
Hãy viết hàm tìm kiếm theo phương pháp tuần tự
11
Vấn đề
int LinearSearch(int a[], int n, int x)
{
Nếu có x thì khơng cần thiết
int i=0;
Có thể loại bỏ?
while ((i
i++;
if(i==N)
return -1; //tìm hết mảng
else
return i; //a[i] là phần tử có khố x
}
12
Cải tiến
Dùng lính canh giúp giảm bớt phép so sánh
Minh họa tìm x =10
10
7
5
12
41
10
10
32
13
9
15
3
10
0
1
2
3
4
5
6
7
8
9
10
Minh họa tìm x = 25
25
7
5
12
41
10
32
13
9
15
3
25
25
0
1
2
3
4
5
6
7
8
9
10
13
Cài đặt
int LinearSearch2(int a[],int n,int x)
{
int i=0;
a[n] = x; // thêm phần tử x sau mảng
while (a[i]!=x )
i++;
if (i==n)
return -1; // tìm hết mảng
else
return i;
// tìm thấy x tại vị trí i
}
Độ phức tạp tính tốn cấp n: T(n)=O(n)
14
Q&A
15
Tìm kiếm nhị phân (Binary Search)
Ý tưởng
Áp dụng đối với dãy số đã có thứ tự
Mỗi bước tiến hành so sánh x với phần tử ở giữa của dãy hiện hành để quyết
định phạm vi tìm kế tiếp
16
Minh họa tìm x = 41
x
x
x
3
14
16
19
22
41
46
51
63
71
0
1
2
3
4
5
6
7
8
9
l
m
m
Tìm thấy x tại vị trí 5
r
m
17
Minh họa tìm x = 45
x
x
x
x
3
14
16
19
22
41
46
51
63
71
0
1
2
3
4
5
6
7
8
9
l
m
m
r
l > r: Kết thúc: Khơng tìm
thấy
m
m
18
Giải thuật
Bước 1: left = 0; right = n-1; //tìm kiếm 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 a[mid] với x, có 3 khả năng :
a[mid] = x: Tìm thấy. Dừng
a[mid] > x: //tìm tiếp x trong dãy con aleft .. amid -1
right = mid - 1;
a[mid] < x: //tìm tiếp x trong dãy con amid +1 .. aright
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ử.
19
Bài tập
Cài đặt hàm tìm kiếm nhị phân bằng phương pháp lặp?
Cài đặt hàm tìm kiếm nhị phân bằng phương pháp đệ quy?
20
Q&A
21
Code minh họa
#include <iostream.h>
#include<stdlib.h>
#include<time.h>
#define MAX 1000
void TaoMang(int a[], int n);
void XuatMang(int a[], int n);
int LinearSearch(int a[], int n, int x);
22
int main()
{
srand((usigned int) time (NULL));
int a[MAX], n = 20, x, vt;
TaoMang(a, n);
XuatMang(a, n);
printf( “Nhap gia tri can tim: “);
scanf(“%d”, &x);
vt=LinearSearch(a, n, x);
if(vt==-1)
printf(“Khong co phan tu can tim”);
else
printf(“Phan tu can tim tai vi tri: %d”, vt);
return 0;
}
23
void TaoMang(int a[], int n)
{
for(int i=0; i
a[i]=rand()%N;
}
void XuatMang(int a[], int n)
{
for(int i=0; i
printf(“%d “, a[i]);
}
24
int LinearSearch(int a[], int n, int x)
{
int i=0;
while ((i
i++;
if(i==n)
return -1;
else
return i;
}
25