8.1. Khái niệm về tìm kiếm (1/3)
Trong thực tế, việc xác định vị trí của một phần tử nào đó
trong một danh sách ( đã sắp xếp hoặc chưa sắp xếp) có
ý nghĩa quan trọng và được dùng trong nhiều ứng dụng.
Ví dụ 1: một chương trình tra cứu từ điển, chương trình
cần trả lời ngay nghĩa của một từ nào đó.
Ví dụ 2: trong một danh sách thí sinh, chương trình cần
đưa ra tất cả thông tin của thí sinh thỏa mãn một số tiêu
chí nào đó.
Những bài toán như vậy được gọi chung là bài toán tìm
kiếm.
8.1. Khái niệm về tìm kiếm (2/3)
Trong thực tế, với các ý tưởng khác nhau dẫn
đến các phương pháp tìm kiếm khác nhau.
Phương pháp tìm kiếm thông dụng nhất trong
thực tế là tìm kiếm tuần tự. Đây là phương pháp
đơn giản, tuy nhiên mất nhiều thời gian thực hiện
đối với dữ liệu lớn
24 trang |
Chia sẻ: thanhle95 | Lượt xem: 623 | Lượt tải: 1
Bạn đang xem trước 20 trang tài liệu Bài giảng Cấu trúc dữ liệu và giải thuật - Bài 8: Các thuật toán tìm kiếm - Ngô Hữu Phước, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
Cấu trúc dữ liệu và giải thuật
Bài 8: Các thuật toán tìm kiếm
PhD. Ngo Huu Phuc, Le Quy Don Technical University1
Giảng viên: TS. Ngo Huu Phuc
Tel: 0438 326 077
Mob: 098 5696 580
Email: ngohuuphuc76@gmail.com
Bài 8. Các thuật toán tìm kiếm
Nội dung:
8.1. Khái niệm về tìm kiếm (3)
8.2. Phương pháp tìm kiếm tuần tự (7)
8.3. Phương pháp tìm kiếm nhị phân (8)
8.4. Phương pháp tìm kiếm nội suy (7)
Tham khảo:
1. Data structures and Algorithms Searching.htm
2. Kyle Loudon Mastering Algorithms, Chapter 12 Sorting and Searching
3. Lecture 19 Sequential and Binary Search.htm
4. Sedgewick Algorithms, Elementary Searching Methods
5. Bài giảng của TS Nguyễn Nam Hồng
PhD. Ngo Huu Phuc, Le Quy Don Technical University2
8.1. Khái niệm về tìm kiếm (1/3)
Trong thực tế, việc xác định vị trí của một phần tử nào đó
trong một danh sách ( đã sắp xếp hoặc chưa sắp xếp) có
ý nghĩa quan trọng và được dùng trong nhiều ứng dụng.
Ví dụ 1: một chương trình tra cứu từ điển, chương trình
cần trả lời ngay nghĩa của một từ nào đó.
Ví dụ 2: trong một danh sách thí sinh, chương trình cần
đưa ra tất cả thông tin của thí sinh thỏa mãn một số tiêu
chí nào đó.
Những bài toán như vậy được gọi chung là bài toán tìm
kiếm.
PhD. Ngo Huu Phuc, Le Quy Don Technical University3
8.1. Khái niệm về tìm kiếm (2/3)
Trong thực tế, với các ý tưởng khác nhau dẫn
đến các phương pháp tìm kiếm khác nhau.
Phương pháp tìm kiếm thông dụng nhất trong
thực tế là tìm kiếm tuần tự. Đây là phương pháp
đơn giản, tuy nhiên mất nhiều thời gian thực hiện
đối với dữ liệu lớn.
PhD. Ngo Huu Phuc, Le Quy Don Technical University4
8.1. Khái niệm về tìm kiếm (3/3)
Phương pháp tìm kiếm nhị phân: chia danh sách thành
các danh sách con và tìm kiếm trên đó. Với bộ dữ liệu lớn,
phương pháp này cho tốc độ tìm kiếm tốt hơn phương
pháp tuần tự.
Phương pháp tìm kiếm nội suy: cũng giống như
phương pháp tìm kiếm nhị phân, phương pháp này cũng
chia danh sách thành các danh sách con và tìm kiếm trên
đó.
Phương pháp tìm kiếm nội suy nhanh hơn phương pháp
nhị phân vì chúng dự đoán kết quả tìm kiếm trên phần nào
để thực hiện tìm kiếm.
PhD. Ngo Huu Phuc, Le Quy Don Technical University5
8.1. Tìm kiếm tuần tự (1/7)
Đây là phương pháp tìm kiếm đơn giản nhất.
Ý tưởng chung của tìm kiếm tuần tự:
Sử dụng vòng lặp để có thể duyệt cả danh sách, xuất
phát từ phần tử đầu tiên trong danh sách.
Tại mỗi bước lặp, so sánh phần tử trong danh sách với
giá trị cần tìm ( theo khóa nào đó ). Quá trình sẽ dừng
nếu tìm thấy đối tượng cần tìm hoặc đã đi hết danh
sách.
PhD. Ngo Huu Phuc, Le Quy Don Technical University6
8.1. Tìm kiếm tuần tự (2/7)
Sub LinearSearch(x:int, a[]: Int, loc: Int)
i:=1
While (ia[i])
i:=i+1
End While
If i<=n Then loc = i Else loc = 0
End Sub
{loc is the subscript of the term that equals x, or is
0 if x is not found}
PhD. Ngo Huu Phuc, Le Quy Don Technical University7
8.1. Tìm kiếm tuần tự (3/7)
Giả sử cho danh sách số nguyên gồm:
Ví dụ: tìm vị trí phần tử có giá trị bằng 11, việc tìm kiếm
bắt đầu từ phần tử có giá trị 17, đến 23, đến 5, đến 11:
đưa ra thông báo đã tìm thấy, trả về vị trí thứ 4 trong
danh sách.
Ví dụ: tìm vị trí phần tử có giá trị bằng 7, việc tìm kiếm bắt
đầu từ phần tử có giá trị 17, qua cả danh sách, nhưng
không tìm thấy, trả về thông tin: không tìm thấy.
PhD. Ngo Huu Phuc, Le Quy Don Technical University8
17 23 5 11 2 29 3
8.1. Tìm kiếm tuần tự (4/7)
Một số ưu điểm của thuật toán tìm kiếm tuần tự:
Rất đơn giản để nắm bắt.
Đơn giản trong việc thực hiện.
Danh sách ban đầu không cần thiết phải được sắp theo
một thứ tự nào đó.
Nhược điểm của phương pháp tìm kiếm tuần tự:
Hiệu quả của phương pháp rất kém.
Ví dụ: Giả sử có một danh sách có 10 000 phần tử.
Phần tử cần tìm ở vị trí 10 000. Như vậy phải đi qua cả
danh sách mới tìm được phần tử đó!!!
PhD. Ngo Huu Phuc, Le Quy Don Technical University9
8.1. Tìm kiếm tuần tự (6/7)
Use a Sentinel to Improve the Performance
Sub LinearSearch2(x:int, a[]: Int, loc: Int)
a[n+1] = x: n = n + 1: i = 1
While (xa[i])
i = i+1
End While
If i<=n Then loc = i Else loc = 0
End Sub
PhD. Ngo Huu Phuc, Le Quy Don Technical University10
8.1. Tìm kiếm tuần tự (7/7)
Apply Linear Search to Sorted Lists
Sub LinearSearch3(x:int, a[]: Int, loc: Int)
i = 1
While (x > a[i])
i = i+1
End While
If a[i] = x Then loc = i Else loc = 0
End Sub
PhD. Ngo Huu Phuc, Le Quy Don Technical University11
8.2. Tìm kiếm nhị phân (1/8)
Với phương pháp tìm kiếm tuần tự, hiệu quả kém
với danh sách dài. Vậy, có cách nào hiệu quả hơn
không?
Phương pháp tốt để tìm kiếm: Tìm kiếm nhị phân.
Giả sử: Cho một danh sách được sắp theo một khóa
nào đó.
Với danh sách này, sử dụng chiến lược “chia để trị” để
tìm kiếm một phần tử.
Phương pháp này gần giống với phương pháp tra từ
điển trong thực tế.
PhD. Ngo Huu Phuc, Le Quy Don Technical University12
8.2. Tìm kiếm nhị phân (2/8)
1. Giả sử dãy khóa đang xét là kl,,kr và cần tìm
phần tử có khóa x.
2. Khóa ở giữa dãy là ki với i = (l+r) / 2.
3. So sánh khóa x với ki, có những khả năng sau:
Nếu x = ki → Kết thúc quá trình tìm kiếm.
Nếu x < ki → Thực hiện việc tìm kiếm trên dãy khóa kl, ,
ki-1.
Nếu x > ki → Thực hiện việc tìm kiếm trên dãy khóa ki+1,
, kr.
4. Thực hiện cho đến khi tìm thấy hoặc khoảng dãy khóa
mới bị rỗng (không tìm thấy).
PhD. Ngo Huu Phuc, Le Quy Don Technical University13
8.2. Tìm kiếm nhị phân (3/8)
Ví dụ về tìm kiếm nhị phân:
Giả sử cho dãy số như sau (đã sắp xếp):
Muốn tìm phần tử có khóa 11, tìm kiếm nhị phân
thấy giá trị 11, dừng tìm kiếm.
Muốn tìm khóa 7, tìm kiếm nhị phân xét các giá trị
lần lượt là 11,3,5, và dừng vị không tìm thấy.
PhD. Ngo Huu Phuc, Le Quy Don Technical University14
2 3 5 11 17 23 29
8.2. Tìm kiếm nhị phân (6/8)
Algorithm for Binary search
Sub BinarySearch(x:int, a[]: int, loc: Int)
i =1: j =n
while i<j
begin
m =(i + j) \ 2
if x > a[m] then i=m+1 else j=m
end
if x=a[i] then loc=i else loc=0
End Sub
PhD. Ngo Huu Phuc, Le Quy Don Technical University15
8.2. Tìm kiếm nhị phân (7/8)
Đánh giá độ phức tạp của tìm kiếm nhị phân
Trường hợp tốt nhất: chỉ mất một lần so sánh, O(1).
Trường hợp xấu nhất:
• Gọi w(n) biểu thị số phép so sánh cho dãy có n phần tử.
• Ta có w(n) = 1 + w(n/2).
• Tương tự, w(n) = 1 + 1 + w(n/4).
•
• Như vậy, ta có w(n) = k + w(n/2k).
• Với n/2k = 1 → k = log2n.
• Độ phức tạp của thuật toán: O(log2n).
Trong trường hợp trung bình đã chứng minh được,
độ phức tạp của thuật toán: O(log2n).
PhD. Ngo Huu Phuc, Le Quy Don Technical University16
8.2. Tìm kiếm nhị phân (8/8)
Nhận xét về tìm kiếm nhị phân
Ưu điểm:
Hiệu quả hơn nhiều so với tìm kiếm tuần tự.
Với dãy có n phần tử, chỉ cần tối đa log2n phép so
sánh.
Nhược điểm:
Dãy đã cho phải được sắp xếp theo một khóa nào đó.
Như vậy, cần thêm thời gian cho sắp xếp.
PhD. Ngo Huu Phuc, Le Quy Don Technical University17
8.3. Tìm kiếm nội suy (1/7)
Tìm kiếm nhị phân hiệu quả hơn nhiều so với tìm
kiếm tuần tự vì nó đã loại bỏ phần lớn phần tử trong
quá trình tìm kiếm.
Trong thực tế, nếu biết thêm thông tin rằng các phần
tử trong danh sách, theo khóa, được phân bố khá
đều, khi đó, có thể sử dụng nội suy để thu ngắn hơn
nữa quá trình tìm kiếm.
PhD. Ngo Huu Phuc, Le Quy Don Technical University18
8.3. Tìm kiếm nội suy (2/7)
Nội suy được hiểu theo nghĩa là từ môt vài giá trị
đã biết, đoán giá trị chưa biết ở vị trí nào.
Ở đây, chỉ số được sử dụng để xác định phần tử
đã biết, cũng như phần tử cần tìm.
Giả sử, tìm kiếm phần tử x từ a[r] đến a[l]. Tìm
kiếm nội suy được thực hiện thông qua công
thức: m = l + (x – a[l])*(r-l)/(a[r]-a[l])
PhD. Ngo Huu Phuc, Le Quy Don Technical University19
8.3. Tìm kiếm nội suy (3/7)
So sánh x với a[m], có một số trường hợp sau:
Nếu x = a[m]: Tìm thấy.
Nếu x < a[m]: đặt r = m-1
Nếu x > a[m]: đặt l = m + 1
Nếu quá trình tìm kiếm chưa kết thúc, tiếp tục tìm
với chỉ số l và r mới.
Quá trình tìm kiếm sẽ dừng khi: tìm thấy, hoặc
xa[r].
PhD. Ngo Huu Phuc, Le Quy Don Technical University20
8.3. Tìm kiếm nội suy (4/7)
Ví dụ: Tìm phần tử có khóa x = 32 trong danh sách
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
19 20
1 4 7 9 9 12 13 17 19 21 24 32 36 44 45 54 55 63
66 70
1: l=1, r=20 -> m=1+(32-1)*(20-1)/(70-1) = 10
a[10]=21 l=11
2: l=11, r=20 -> m=11+(30-24)*(20-11)/(70-24) = 12
a[12]=32=x -> Found at m = 12
PhD. Ngo Huu Phuc, Le Quy Don Technical University21
8.3. Tìm kiếm nội suy (5/7)
Ví dụ: Tìm phần tử có khóa x = 30 trong danh sách
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
19 20
1 4 7 9 9 12 13 17 19 21 24 32 36 44 45 54 55 63
66 70
1: l=1, r=20 -> m=1+(30-1)*(20-1)/(70-1) = 9
a[9]=19 l=10
2: l=10, r=20 -> m=10+(30-21)*(20-10)/(70-21) =
12
a[12]=32>30=x -> r = 11
3: l=10, r=11 -> m=10+(30-24)*(11-10)/(24-21) = 12
m=12>11=r: Not FoundPhD. Ngo Huu Phuc, Le Quy Don Technical University22
8.3. Tìm kiếm nội suy (6/7)
Private Sub Interpolation(a[]: Int, x: Int, n: Int, Found:
Boolean)
l = 1: r = n
Do While (r > l)
m = l + ((x – a[l]) / (a[r] – a[l])) * (r - l)
If (a[m] = x) Or (m r) Then
If (a[m] = x) Then Found = True Else Found = False
Exit Do
ElseIf (a[m] < x) Then
l = m + 1
ElseIf (a[m] > x) Then
r = m - 1
End If
Loop
End Sub
PhD. Ngo Huu Phuc, Le Quy Don Technical University23
8.3. Tìm kiếm nội suy (7/7)
Nhận xét:
Tìm kiếm nhị phân cho tốc độ tìm kiếm nhanh (độ phức
tạp O(logn)). Tuy nhiên, tìm kiếm nội suy cho tốc độ tìm
kiếm tốt hơn (độ phức tạp O(loglogn)).
Ví dụ, với n = 2^32 (4 tỉ phần tử)
Tìm kiếm nhị phân cần khoảng 32 bước.
Tìm kiếm nội suy cần khoảng 5 bước.
Tìm kiếm nội suy hiệu quả với danh sách có số phần tử
lớn.
Tìm kiếm nội suy vẫn được dùng trong tìm kiếm dữ liệu
được lưu trữ trên ổ cứng hoặc các thiết bị truy cập chậm
khác.PhD. Ngo Huu Phuc, Le Quy Don Technical University24