1.2. THUẬT TOÁN TÌM KIẾM.
1.2.1. Bài toán tìm kiếm:
Bài toán xác định vị trí của một phần tử trong một bảng liệt kê sắp thứ tự thường gặp trong nhiều trường hợp khác nhau. Chẳng hạn chương trình kiểm tra chính tả của các từ, tìm kiếm các từ này trong một cuốn từ điển, mà từ điển chẳng qua cũng là một bảng liệt kê sắp thứ tự của các từ. Các bài toán thuộc loại này được gọi là các bài toán tìm kiếm.Bài toán tìm kiếm tổng quát được mô tả như sau: xác định vị trí của phần tử x trong một bảng liệt kê các phần tử phân biệt a1,a2, ..., an hoặc xác định rằng nó không có mặt trong bảng liệt kê đó. L ời giải của bài toán trên là vị trí của số hạng của bảng liệt kê có giá trị bằng x (tức là i sẽ là nghiệm nếu x=ai và là 0 nếu x không có mặt trong bảngliệt kê).
1.2.2. Thuật toán tìm kiếm tuyến tính:
Tìm kiếm tuyến tính hay tìm kiếm tuần tự là bắt đầu bằng việc so sánh x với a1; khi x = a1, nghiệm là vị trí a1, tức là 1; khi x != a1, so sánh x với a2. Nếu x = a2, nghiệm l à vị trí của a2, tức là 2. Khi x != a2, so sánh x với a3. Tiếp tục quá trình này b ằng cách tuần tự so sánh x với mỗi số hạng của bảng liệt kê cho tới khi tìm được số hạng bằng x, khi đó nghiệm là vị trí của số hạng đó. Nếu toàn bảng liệt kê đã được kiểm tra mà không xác định được vị trí của x, thì nghi ệm là 0. Giả mã đối với thuật toán tìm kiếm tuyến tính được cho dưới đây:procedure tìm kiếm tuyến tính (x: integer, a1,a2,...,an: integers phân biệt)
i := 1
while (i <= n and x != ai)
i := i + 1
if i <= n then location := i
else location := 0{location là chỉ số dưới của số hạng bằng x hoặc là 0 nếu không tìm được x}
1.2.3. Thuật toán tìm ki ếm nhị phân:
Thuật toán này có thể được dùng khi bảng liệt kê có các số hạng được sắp theo thứ tự tă ng dần. Chẳng hạn, nếu các số hạng là các số thì chúng được sắp từ số nhỏ nhất đến số lớn nhất hoặc nếu chúng là các từ hay xâu ký tự thì chúng được sắp theo thứ tự từ điển. Thuật toán thứ hai này gọi là thuật toán tìm kiếm nhị phân. Nó được tiến hành bằng cách so sánh phần tử cần xác định vị trí với số hạng ở giữa bảng liệt kê. Sau đó bảng này được tách làm hai bảng kê con nhỏ hơn có kích thước như nhau, hoặc một trong hai bảng con ít hơn bảng con kia một số hạng. Sự tìm ki ếm tiếp tục bằng cách hạn chế tìm kiếm ở một bảng kê con thích hợp dựa trên việc so sánh phần tử cần xác định vị trí với số hạng giữa bảng kê. Ta sẽ thấy rằng thuật toán tìm kiếm nhị phân hiệu quả hơn nhiều so với thuật toán tìm kiếm tuyến tính.Thí dụ 2. Để tìm số 19 trong bảng liệt kê 1,2,3,5,6,7,8,10,12,13,15,16,18,19,20,22 ta tách bảng liệt kê gồm 16 số hạng này thành hai bảng liệt kê nhỏ hơn, mỗi bảng có 8 số hạng, cụ thể là: 1,2,3,5,6,7,8,10 và 12,13,15,16,18,19,20,22.
Sau đó ta so sánh 19 với số hạng cuối cùng của bảng con thứ nhất . Vì 10<19, vi ệc tìm kiếm 19 chỉ giới hạn trong bảng liệt kê con thứ 2 từ số hạng thứ 9 đến 16 trong bảng liệt kê ban đầu.
Tiếp theo, ta lại tách bảng liệt kê con g ồm 8 số hạng này làm hai bảng con, mỗi bảng có 4 số hạng, cụ thể là 12,13,15,16 và 18,19,20, 22. Vì 16<19, việc tìm ki ếm lại được giới hạn chỉ trong bảng con thứ 2, từ số hạng thứ 13 đến 16 của bảng liệt kê ban đầu. Bảng liệt kê thứ 2 này lại được tách làm hai, cụ thể là: 18,19 và 20,22. Vì 19 không lớn hơn số hạng lớn nhất của bảng con thứ nhất nên vi ệc tìm kiếm giới hạn chỉ ở bảng con thứ nhất gồm các số 18,19, l à số hạng thứ 13 và 14 của bảng ban đầu.
Tiếp theo bảng con chứa hai số hạng này lại được tách làm hai, mỗi bảng có một số hạng 18 và 19. Vì 18<19, s ự tìm kiếm giới hạn chỉ trong bảng con thứ 2, bảng liệt kê chỉ chứa số hạng thứ 14 của bảng liệt kê ban đầu, số hạng đó là s ố 19. Bây giờ sự tìm kiếm đã thu hẹp về chỉ còn một số hạng, so sánh tiếp cho thấy19 là số hạng thứ 14 của bảng liệt kê ban đầu. Bây giờ ta có thể chỉ rõ các bước trong thu ật toán t ìm kiếm nhị phân. Để tìm số nguyên x trong bảng liệt kê a1,a2,...,an với a1< a2< ... < an, ta bắt đầu bằng việc so sánh x với số hạng am ở giữa của dãy, với m=[(n+1)/2]. Nếu x > am, việc tìm kiếm x giới hạn ở nửa thứ hai của dãy, gồm am+1,am+2,...,an. Nếu x không lớn hơn am, thì sự tìm kiếm giới hạn trong nửa đầu của dãy gồm a1,a2,...,am.
Bây giờ sự tìm kiếm chỉ giới hạn trong bảng liệt kê có không hơn [n/2] phần tử. Dùng chính thủ tục này, so sánh x với số hạng ở giữa của bảng liệt kê được hạn chế. Sau đó lại hạn chế việc t ìm kiếm ở nửa thứ nhất hoặc nửa thứ hai của bảng liệt kê. Lặp lại quá trình này cho tới khi nhận được một bảng liệt kê chỉ có một số hạng. Sau đó, chỉ còn xác định số hạng này có phải là x hay không. Giả mã cho thuật toán tìm kiếm nhị phân được cho dưới đây:procedure tìm ki ếm nhị phân (x: integer, a1,a2,...,an: integers tăng dần)
i := 1 {i là đi ểm mút trái của khoảng tìm kiếm}
j := n {j là đi ểm mút phải của khoảng tìm kiếm}
while i < j
begin
m:= [(i+j)/2]
if x>am
then i:=m+1
else j := m
end
if x = ai then location := i
else location := 0{location là chỉ số dưới của số hạng bằng x hoặc 0 nếu không tìm thấy x}