3.1 Bài toán tìm phần tử trong mảng sử dụng tìm kiếm tuyến tính
Bài toán: Cho một mảng số. Cần tìm chỉ số của số đã cho bằng cách sử dụng tìm kiếm tuyến tính. Nếu số không được tìm thấy, trả về -1.
Ví dụ:
def linear_search(arr, target):
for index, element in enumerate(arr):
if element == target:
return index
return -1
# Ví dụ sử dụng:
arr = [4, 2, 7, 1, 9, 3]
target = 7
result = linear_search(arr, target)
print(f"Phần tử {target} được tìm thấy ở chỉ số {result}") # Kết quả: Phần tử 7 được tìm thấy ở chỉ số 2
# Ví dụ sử dụng cho phần tử không có trong mảng:
target = 5
result = linear_search(arr, target)
print(f"Phần tử {target} được tìm thấy ở chỉ số {result}") # Kết quả: Phần tử 5 được tìm thấy ở chỉ số -1
Giải thích:
- Hàm
linear_search
duyệt qua từng phần tử trong mảng arr và so sánh nó vớitarget
. - Nếu phần tử được tìm thấy, trả về chỉ số của nó.
- Nếu tất cả phần tử đã được kiểm tra và giá trị cần tìm không được tìm thấy, hàm trả về -1.
Thực hiện từng bước:
- Mảng
[4, 2, 7, 1, 9, 3]
và giá trị cần tìm7
. - Bắt đầu tìm kiếm: so sánh phần tử đầu tiên (4) với 7 — không khớp.
- Chuyển sang phần tử tiếp theo
(2)
— không khớp. - Chuyển sang phần tử tiếp theo
(7)
— khớp. - Trả về chỉ số
2
.
3.2 Bài toán tìm phần tử trong mảng đã sắp xếp sử dụng tìm kiếm nhị phân
Bài toán: Cho một mảng số đã sắp xếp. Cần tìm chỉ số của số đã cho bằng cách sử dụng tìm kiếm nhị phân. Nếu số không được tìm thấy, trả về -1.
Ví dụ:
def binary_search(arr, target):
left, right = 0, len(arr) - 1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
# Ví dụ sử dụng:
sorted_array = [1, 3, 5, 7, 9, 11, 13]
target = 7
result = binary_search(sorted_array, target)
print(f"Phần tử {target} được tìm thấy ở chỉ số {result}") # Kết quả: Phần tử 7 được tìm thấy ở chỉ số 3
# Ví dụ sử dụng cho phần tử không có trong mảng:
target = 6
result = binary_search(sorted_array, target)
print(f"Phần tử {target} được tìm thấy ở chỉ số {result}") # Kết quả: Phần tử 6 được tìm thấy ở chỉ số -1
Giải thích:
- Hàm
binary_search
sử dụng hai chỉ báo (left và right), để theo dõi giới hạn tìm kiếm trong mảngarr
. - Ở mỗi vòng lặp, tìm phần tử giữa của mảng và so sánh với
target
. - Nếu phần tử giữa bằng
target
, trả về chỉ số của nó. - Nếu
target
nhỏ hơn phần tử giữa, tìm kiếm tiếp ở nửa trái của mảng. - Nếu
target
lớn hơn phần tử giữa, tìm kiếm tiếp ở nửa phải của mảng. - Nếu giới hạn giao nhau và phần tử không được tìm thấy, trả về -1.
Thực hiện từng bước:
- Mảng đã sắp xếp
[1, 3, 5, 7, 9, 11, 13]
và giá trị cần tìm7
. - Giới hạn tìm kiếm ban đầu:
left = 0
,right = 6
. - Tìm phần tử giữa:
mid = (0 + 6) // 2 = 3
. - So sánh phần tử giữa
(7)
vớitarget (7)
— khớp. - Trả về chỉ số
3
.
3.3 So sánh và lựa chọn thuật toán tìm kiếm thích hợp cho các bài toán khác nhau
So sánh tìm kiếm tuyến tính và nhị phân:
Đặc điểm | Tìm kiếm tuyến tính | Tìm kiếm nhị phân |
---|---|---|
Độ phức tạp thời gian | O(n) | O(log n) |
Yêu cầu dữ liệu | Không yêu cầu sắp xếp trước | Yêu cầu mảng đã sắp xếp |
Đơn giản trong triển khai | Rất đơn giản | Phức tạp hơn |
Hiệu quả | Kém hiệu quả cho mảng lớn | Rất hiệu quả cho mảng lớn |
Lựa chọn thuật toán phù hợp
Tìm kiếm tuyến tính:
- Được sử dụng khi dữ liệu chưa được sắp xếp.
- Phù hợp cho mảng hoặc danh sách nhỏ.
- Áp dụng khi số lượng phần tử không lớn và thời gian thực thi không quan trọng.
Tìm kiếm nhị phân:
- Áp dụng khi dữ liệu đã được sắp xếp.
- Lý tưởng cho mảng lớn, nơi tốc độ tìm kiếm quan trọng.
- Hiệu quả nếu
yêu cầu tìm kiếm thường xuyên trên cùng một tập dữ liệu
(có thể sắp xếp dữ liệu trước).
3.4 Bài tập thực hành để củng cố kiến thức
Bài tập 1: Tìm kiếm tuyến tính
Cho một mảng số. Viết hàm tìm kiếm số đã cho bằng cách sử dụng tìm kiếm tuyến tính. Hàm phải trả về chỉ số của phần tử đã tìm thấy hoặc -1 nếu không tìm thấy phần tử.
Ví dụ:
def linear_search(arr, target):
for index, element in enumerate(arr):
if element == target:
return index
return -1
# Ví dụ sử dụng:
arr = [4, 2, 7, 1, 9, 3]
target = 7
result = linear_search(arr, target)
print(f"Phần tử {target} được tìm thấy ở chỉ số {result}") # Kết quả: Phần tử 7 được tìm thấy ở chỉ số 2
# Các bài kiểm tra bổ sung:
assert linear_search(arr, 9) == 4
assert linear_search(arr, 5) == -1
Bài tập 2: Tìm kiếm nhị phân
Cho một mảng số đã sắp xếp. Viết hàm tìm kiếm số đã cho bằng cách sử dụng tìm kiếm nhị phân. Hàm phải trả về chỉ số của phần tử đã tìm thấy hoặc -1 nếu không tìm thấy phần tử.
Ví dụ:
def binary_search(arr, target):
left, right = 0, len(arr) - 1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
# Ví dụ sử dụng:
sorted_array = [1, 3, 5, 7, 9, 11, 13]
target = 7
result = binary_search(sorted_array, target)
print(f"Phần tử {target} được tìm thấy ở chỉ số {result}") # Kết quả: Phần tử 7 được tìm thấy ở chỉ số 3
# Các bài kiểm tra bổ sung:
assert binary_search(sorted_array, 1) == 0
assert binary_search(sorted_array, 13) == 6
assert binary_search(sorted_array, 6) == -1
Bài tập 3: So sánh tìm kiếm tuyến tính và nhị phân
Cho một mảng số. Viết hai hàm để tìm kiếm số đã cho: một sử dụng tìm kiếm tuyến tính, một sử dụng tìm kiếm nhị phân. So sánh hiệu suất của cả hai hàm trên các mảng lớn.
Ví dụ:
import time
import random
# Tìm kiếm tuyến tính
def linear_search(arr, target):
for index, element in enumerate(arr):
if element == target:
return index
return -1
# Tìm kiếm nhị phân
def binary_search(arr, target):
left, right = 0, len(arr) - 1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
# Tạo mảng lớn
large_array = [random.randint(0, 1000000) for _ in range(1000000)]
sorted_large_array = sorted(large_array)
target = random.choice(large_array)
# So sánh hiệu suất
start_time = time.time()
linear_search(large_array, target)
print(f"Tìm kiếm tuyến tính mất: {time.time() - start_time:.6f} giây")
start_time = time.time()
binary_search(sorted_large_array, target)
print(f"Tìm kiếm nhị phân mất: {time.time() - start_time:.6f} giây")
GO TO FULL VERSION