Ch ng 2:ươ TÌM KI MẾTÌM KI MẾ
(SEARCHING)
Ch ng 2:ươ Tìm
Nội dung
1. Khái quát về tìm kiếm
2. Tìm tuyến tính (Linear Search)
3. Tìm nhị phân (Binary Search)
2
Ch ng 2:ươ Tìm
Khái quát về tìm kiếm
 Tìm kiếm là một yêu cầu rất thường xuyên trong đời
sống hàng ngày cũng như trong tin học
 Ví dụ:
 Tìm kiếm một sinh viên trong lớp
 Tìm kiếm một tập tin, thư mục trong máy
 Để đơn giản, xét bài toán tìm kiếm như sau:
 Cho một dãy số gồm các phần tử a1, a2, ..., an. Cho biết
trong dãy này có phần tử nào có giá trị bằng X (cho trước)
hay không?
3
Ch ng 2:ươ Tìm
Khái quát về tìm kiếm
 Xét hai cách tìm kiếm:
 Tìm kiếm tuyến tính (Linear Search) hay còn gọi là tìm
kiếm tuần tự (Sequential Search)
 Tìm kiếm nhị phân (Binary Search)
4
Ch ng 2:ươ Tìm
Nội dung
1. Khái quát về tìm kiếm
2. Tìm tuyến tính (Linear Search)
3. Tìm nhị phân (Binary Search)
5
Ch ng 2:ươ Tìm
2. Tìm tuyến tính (Linear Seach)
Ý tưởng:
 Bắt đầu từ phần tử đầu tiên của danh sách, so sánh lần
lượt từng phần tử của danh sách với giá trị X cần tìm
 Nếu có phần tử bằng X thì trả về vị trí tìm thấy, thuật toán
dừng lại (thành công)
 Nếu đến cuối danh sách mà không có phần tử nào bằng X,
thuật toán dừng lại (không thành công)
6
Ch ng 2:ươ Tìm
2. Tìm tuyến tính (Linear Seach)
Thuật toán:
Input: Danh sách A và phần tử cần tìm X
B1: i = 0 ; // bắt đầu từ phần tử đầu tiên
B2: so sánh A[i] với X, có 2 khả năng :
 A[i] = X : Tìm thấy X tại vị trí i. Dừng
 A[i] ≠ X : Sang B3
B3: i=i+1 // Xét phần tử tiếp theo 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 B2
7
Ch ng 2:ươ Tìm
13
1 2 n
3 5 10 13 6 9
A[0] A[n-1]
i=0 i=1i i=2 i=3
3 Tìm thấy tại
vị trí 419
i=4 i=5
-1
Tìm Ko thấy
Ch ng 2:ươ Tìm
2. Tìm tuyến tính (Linear Seach)
9
13
0 1 5
3 5 10 13 6 9
A[0] A[n-1]
i=0 i=1i i=2 i=3
3 Tìm thấy tại
vị trí 319
i=4 i=5
-1
Tìm Ko thấy
Ch ng 2:ươ Tìm
2. Tìm tuyến tính (Linear Seach)
10
Thuật Giải :
Hàm LinearSearch
Cho i = 0
Thực hiện
Nếu a[i] == x thì
dừng ct, trả về kết quả tìm thấy
ngược lại tăng i thêm 1
Lặp lại thực hiện đến khi i >= n
Trả về kết quả tìm không thấy
Hàm LinearSearch
Cho i = 0
Thực hiện
Nếu a[i] == x thì
dừng ct, trả về kết quả tìm thấy
ngược lại tăng i thêm 1
Lặp lại thực hiện đến khi i >= n
Trả về kết quả tìm không thấy
int LinearSearch(int A[], int n, int x)
{
int i = 0;
do
{
if (A[i] == x)
return i;
else
i++;
} while (i < n);
return -1;
}
int LinearSearch(int A[], int n, int x)
{
int i = 0;
do
{
if (A[i] == x)
return i;
else
i++;
} while (i < n);
return -1;
}
Cài đặt chương trình
Ch ng 2:ươ Tìm
Nội dung
1. Khái quát về tìm kiếm
2. Tìm tuyến tính (Linear Search)
3. Tìm nhị phân (Binary Search)
11
Ch ng 2:ươ Tìm
3. Tìm nhị phân (Binary Seach)
 Điều kiện:
 Danh sách phải được sắp xếp trước
 Ý tưởng:
 So sánh giá trị muốn tìm X với phần tử nằm ở vị trí giữa
của danh sách:
 Nếu bằng, tìm kiếm dừng lại (thành công)
 Nếu X lớn hơn thì tiếp tục tìm kiếm ở phần danh sách bên phải
phần tử giữa
 Nếu X nhỏ hơn thì tiếp tục tìm kiếm ở phần danh sách bên trái
phần tử giữa
12
Ch ng 2:ươ Tìm
3. Tìm nhị phân (Binary Seach)
Thuật toán:
Input: Danh sách A đã được sắp xếp và phần tử cần tìm X
B1: Left = 0, Right = n-1
B2: Mid = (Left + Right)/2 // lấy vị trí cận giữa
B3: So sánh X với A[Mid], có 3 khả năng xảy ra:
 A[Mid] = X // tìm thấy. Dừng thuật toán
 A[Mid] > X
Right = Mid-1 // Tiếp tục tìm trong dãy A[0]… A[Mid-1]
 A[Mid] < X
Left = Mid+1 // Tiếp tục tìm trong dãy A[Mid+1]… A[Right]
B4: Nếu (Left <= Right) // Còn phần tử chưa xét
Lặp lại B2
Ngược lại: Kết thúc
13
Ch ng 2:ươ Tìm
3. Tìm nhị phân (Binary Seach)
14
Left Right
36
m=(Left + Right)/2
= (0+11)/2
= 5
A[m]
m=(Left + Right)/2
= (6+11)/2
= 8
A[m]
m=(Left + Right)/2
= (9+11)/2
= 10
A[m]
Tìm thấy tại
vị trí 10
m
0 1 2 3 4 5 6 7 8 9 10 11
Ch ng 2:ươ Tìm
3. Tìm nhị phân (Binary Seach)
15
0 1 2 3 4 5 6 7 8 9 10 11
Left Right
23
m=(Left + Right)/2
= (0+11)/2
= 5
A[m]
m=(Left + Right)/2
= (6+11)/2
= 8
A[m]
m=(Left + Right)/2
= (6+7)/2
= 6
A[m]
Tìm thấy tại
vị trí 6
m
Ch ng 2:ươ Tìm
3. Tìm nhị phân (Binary Seach)
16
0 1 2 3 4 5 6 7 8 9 10 11
Left Right
24
m=(Left + Right)/2
= (0+11)/2
= 5
A[m]
m=(Left + Right)/2
= (6+11)/2
= 8
A[m]
m=(Left + Right)/2
= (6+7)/2
= 6
A[m]
Tìm ko thấy
-1
m=(Left + Right)/2
= (7+7)/2
= 7
A[m]
Ch ng 2:ươ Tìm
3. Tìm nhị phân (Binary Seach)
17
Thuật Giải :
Hàm BinarySearch
Cho Left = 0, Right = n-1
Thực hiện trong khi Left <= Right
m=(Left + Right)/2
Nếu a[m] == x thì
dừng ct, trả về kết quả tìm thấy (m)
ngược lại
nếu x > a[m] thì Left = m+1
ngược lại Right = m-1
Kết thúc tìm kiếm trong mảng tìm không
thấy Trả về kết quả tìm không thấy (-1)
Hàm BinarySearch
Cho Left = 0, Right = n-1
Thực hiện trong khi Left <= Right
m=(Left + Right)/2
Nếu a[m] == x thì
dừng ct, trả về kết quả tìm thấy (m)
ngược lại
nếu x > a[m] thì Left = m+1
ngược lại Right = m-1
Kết thúc tìm kiếm trong mảng tìm không
thấy Trả về kết quả tìm không thấy (-1)
int BinarySearch(int A[], int n, int x)
{
int L = 0, R = n-1, m;
while (L<=R)
{
m = (L + R) /2;
if (A[m] == x)
return m; //Tìm thấy x
else
if (x > A[m] )
L = m +1;
else
R = m -1;
}
return -1; //Kết luận không tìm thây x
}
int BinarySearch(int A[], int n, int x)
{
int L = 0, R = n-1, m;
while (L<=R)
{
m = (L + R) /2;
if (A[m] == x)
return m; //Tìm thấy x
else
if (x > A[m] )
L = m +1;
else
R = m -1;
}
return -1; //Kết luận không tìm thây x
}
Cài đặt chương trình
Ch ng 2:ươ Tìm
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
 Tất cả các nhu cầu đó tạo ra khuyết điểm chính cho giải
thuật tìm Nhị Phân
 Ta 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
18

C2 tim kiem

  • 1.
    Ch ng 2:ươTÌM KI MẾTÌM KI MẾ (SEARCHING)
  • 2.
    Ch ng 2:ươTìm Nội dung 1. Khái quát về tìm kiếm 2. Tìm tuyến tính (Linear Search) 3. Tìm nhị phân (Binary Search) 2
  • 3.
    Ch ng 2:ươTìm Khái quát về tìm kiếm  Tìm kiếm là một yêu cầu rất thường xuyên trong đời sống hàng ngày cũng như trong tin học  Ví dụ:  Tìm kiếm một sinh viên trong lớp  Tìm kiếm một tập tin, thư mục trong máy  Để đơn giản, xét bài toán tìm kiếm như sau:  Cho một dãy số gồm các phần tử a1, a2, ..., an. Cho biết trong dãy này có phần tử nào có giá trị bằng X (cho trước) hay không? 3
  • 4.
    Ch ng 2:ươTìm Khái quát về tìm kiếm  Xét hai cách tìm kiếm:  Tìm kiếm tuyến tính (Linear Search) hay còn gọi là tìm kiếm tuần tự (Sequential Search)  Tìm kiếm nhị phân (Binary Search) 4
  • 5.
    Ch ng 2:ươTìm Nội dung 1. Khái quát về tìm kiếm 2. Tìm tuyến tính (Linear Search) 3. Tìm nhị phân (Binary Search) 5
  • 6.
    Ch ng 2:ươTìm 2. Tìm tuyến tính (Linear Seach) Ý tưởng:  Bắt đầu từ phần tử đầu tiên của danh sách, so sánh lần lượt từng phần tử của danh sách với giá trị X cần tìm  Nếu có phần tử bằng X thì trả về vị trí tìm thấy, thuật toán dừng lại (thành công)  Nếu đến cuối danh sách mà không có phần tử nào bằng X, thuật toán dừng lại (không thành công) 6
  • 7.
    Ch ng 2:ươTìm 2. Tìm tuyến tính (Linear Seach) Thuật toán: Input: Danh sách A và phần tử cần tìm X B1: i = 0 ; // bắt đầu từ phần tử đầu tiên B2: so sánh A[i] với X, có 2 khả năng :  A[i] = X : Tìm thấy X tại vị trí i. Dừng  A[i] ≠ X : Sang B3 B3: i=i+1 // Xét phần tử tiếp theo 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 B2 7
  • 8.
    Ch ng 2:ươTìm 13 1 2 n 3 5 10 13 6 9 A[0] A[n-1] i=0 i=1i i=2 i=3 3 Tìm thấy tại vị trí 419 i=4 i=5 -1 Tìm Ko thấy
  • 9.
    Ch ng 2:ươTìm 2. Tìm tuyến tính (Linear Seach) 9 13 0 1 5 3 5 10 13 6 9 A[0] A[n-1] i=0 i=1i i=2 i=3 3 Tìm thấy tại vị trí 319 i=4 i=5 -1 Tìm Ko thấy
  • 10.
    Ch ng 2:ươTìm 2. Tìm tuyến tính (Linear Seach) 10 Thuật Giải : Hàm LinearSearch Cho i = 0 Thực hiện Nếu a[i] == x thì dừng ct, trả về kết quả tìm thấy ngược lại tăng i thêm 1 Lặp lại thực hiện đến khi i >= n Trả về kết quả tìm không thấy Hàm LinearSearch Cho i = 0 Thực hiện Nếu a[i] == x thì dừng ct, trả về kết quả tìm thấy ngược lại tăng i thêm 1 Lặp lại thực hiện đến khi i >= n Trả về kết quả tìm không thấy int LinearSearch(int A[], int n, int x) { int i = 0; do { if (A[i] == x) return i; else i++; } while (i < n); return -1; } int LinearSearch(int A[], int n, int x) { int i = 0; do { if (A[i] == x) return i; else i++; } while (i < n); return -1; } Cài đặt chương trình
  • 11.
    Ch ng 2:ươTìm Nội dung 1. Khái quát về tìm kiếm 2. Tìm tuyến tính (Linear Search) 3. Tìm nhị phân (Binary Search) 11
  • 12.
    Ch ng 2:ươTìm 3. Tìm nhị phân (Binary Seach)  Điều kiện:  Danh sách phải được sắp xếp trước  Ý tưởng:  So sánh giá trị muốn tìm X với phần tử nằm ở vị trí giữa của danh sách:  Nếu bằng, tìm kiếm dừng lại (thành công)  Nếu X lớn hơn thì tiếp tục tìm kiếm ở phần danh sách bên phải phần tử giữa  Nếu X nhỏ hơn thì tiếp tục tìm kiếm ở phần danh sách bên trái phần tử giữa 12
  • 13.
    Ch ng 2:ươTìm 3. Tìm nhị phân (Binary Seach) Thuật toán: Input: Danh sách A đã được sắp xếp và phần tử cần tìm X B1: Left = 0, Right = n-1 B2: Mid = (Left + Right)/2 // lấy vị trí cận giữa B3: So sánh X với A[Mid], có 3 khả năng xảy ra:  A[Mid] = X // tìm thấy. Dừng thuật toán  A[Mid] > X Right = Mid-1 // Tiếp tục tìm trong dãy A[0]… A[Mid-1]  A[Mid] < X Left = Mid+1 // Tiếp tục tìm trong dãy A[Mid+1]… A[Right] B4: Nếu (Left <= Right) // Còn phần tử chưa xét Lặp lại B2 Ngược lại: Kết thúc 13
  • 14.
    Ch ng 2:ươTìm 3. Tìm nhị phân (Binary Seach) 14 Left Right 36 m=(Left + Right)/2 = (0+11)/2 = 5 A[m] m=(Left + Right)/2 = (6+11)/2 = 8 A[m] m=(Left + Right)/2 = (9+11)/2 = 10 A[m] Tìm thấy tại vị trí 10 m 0 1 2 3 4 5 6 7 8 9 10 11
  • 15.
    Ch ng 2:ươTìm 3. Tìm nhị phân (Binary Seach) 15 0 1 2 3 4 5 6 7 8 9 10 11 Left Right 23 m=(Left + Right)/2 = (0+11)/2 = 5 A[m] m=(Left + Right)/2 = (6+11)/2 = 8 A[m] m=(Left + Right)/2 = (6+7)/2 = 6 A[m] Tìm thấy tại vị trí 6 m
  • 16.
    Ch ng 2:ươTìm 3. Tìm nhị phân (Binary Seach) 16 0 1 2 3 4 5 6 7 8 9 10 11 Left Right 24 m=(Left + Right)/2 = (0+11)/2 = 5 A[m] m=(Left + Right)/2 = (6+11)/2 = 8 A[m] m=(Left + Right)/2 = (6+7)/2 = 6 A[m] Tìm ko thấy -1 m=(Left + Right)/2 = (7+7)/2 = 7 A[m]
  • 17.
    Ch ng 2:ươTìm 3. Tìm nhị phân (Binary Seach) 17 Thuật Giải : Hàm BinarySearch Cho Left = 0, Right = n-1 Thực hiện trong khi Left <= Right m=(Left + Right)/2 Nếu a[m] == x thì dừng ct, trả về kết quả tìm thấy (m) ngược lại nếu x > a[m] thì Left = m+1 ngược lại Right = m-1 Kết thúc tìm kiếm trong mảng tìm không thấy Trả về kết quả tìm không thấy (-1) Hàm BinarySearch Cho Left = 0, Right = n-1 Thực hiện trong khi Left <= Right m=(Left + Right)/2 Nếu a[m] == x thì dừng ct, trả về kết quả tìm thấy (m) ngược lại nếu x > a[m] thì Left = m+1 ngược lại Right = m-1 Kết thúc tìm kiếm trong mảng tìm không thấy Trả về kết quả tìm không thấy (-1) int BinarySearch(int A[], int n, int x) { int L = 0, R = n-1, m; while (L<=R) { m = (L + R) /2; if (A[m] == x) return m; //Tìm thấy x else if (x > A[m] ) L = m +1; else R = m -1; } return -1; //Kết luận không tìm thây x } int BinarySearch(int A[], int n, int x) { int L = 0, R = n-1, m; while (L<=R) { m = (L + R) /2; if (A[m] == x) return m; //Tìm thấy x else if (x > A[m] ) L = m +1; else R = m -1; } return -1; //Kết luận không tìm thây x } Cài đặt chương trình
  • 18.
    Ch ng 2:ươTìm 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  Tất cả các nhu cầu đó tạo ra khuyết điểm chính cho giải thuật tìm Nhị Phân  Ta 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 18