Có nhiều cách để tìm một phần tử trong dữ liệu. Mỗi thuật toán có ưu điểm và nhược điểm riêng. Tùy vào dữ liệu mà chúng ta chọn thuật toán phù hợp.
Ý tưởng:
Kiểm tra từng phần tử từ đầu đến cuối cho đến khi tìm thấy.
Ví dụ:
a = [12, 5, 31, 18, 7]
x = 18
for i in range(len(a)):
if a[i] == x:
print("Tìm thấy tại vị trí", i)
break
Ưu điểm
Nhược điểm
Độ phức tạp:
O(n)
Ý tưởng:
Luôn kiểm tra phần tử ở giữa danh sách.
Nếu giá trị cần tìm lớn hơn phần tử giữa thì bỏ nửa bên trái.
Nếu nhỏ hơn thì bỏ nửa bên phải.
Ví dụ:
3 7 9 12 18 25 31 40
↑
Tìm số 31
31 > 18 Bỏ nửa bên trái.
Độ phức tạp:
O(log n)
Điều kiện:
Ý tưởng:
Không tìm từng phần tử mà nhảy từng đoạn.
Ví dụ:
1 2 3 [4] 5 6 7 [8] 9 10 11 [12] 13 14 15 [16]
Tìm số 10
Kiểm tra 4 ↓ Kiểm tra 8 ↓ Kiểm tra 12 ↓ Biết 10 nằm giữa 8 và 12 ↓ Tìm tuần tự trong đoạn đó.
Độ phức tạp:
O(√n)
Ý tưởng:
Thay vì luôn chọn phần tử ở giữa, thuật toán sẽ dự đoán vị trí của giá trị cần tìm.
Ví dụ:
10 20 30 40 50 60 70 80 90
Tìm số 80
Binary Search sẽ kiểm tra giữa trước.
Interpolation Search sẽ đoán gần cuối dãy nên thường nhanh hơn nếu dữ liệu phân bố đều.
Độ phức tạp trung bình:
O(log log n)
Ý tưởng:
Áp dụng khi dữ liệu được lưu dưới dạng cây nhị phân tìm kiếm (Binary Search Tree).
Ví dụ:
20
/ \
10 35
/ \ / \
5 15 30 40
Tìm số 30
20 ↓ 35 ↓ 30
Độ phức tạp:
O(log n)
(Nếu cây cân bằng.)
Ý tưởng:
Lưu dữ liệu theo khóa (key), giúp tra cứu gần như ngay lập tức.
Ví dụ:
hoc_sinh = {
"An": 9,
"Bình": 8,
"Lan": 10
}
print(hoc_sinh["Lan"])
Độ phức tạp trung bình:
O(1)
Python sử dụng Hash Table cho kiểu dữ liệu Set.
s = {5, 12, 18, 30}
if 18 in s:
print("Có")
Độ phức tạp trung bình:
O(1)
Ví dụ:
a = [5, 8, 10, 13] print(10 in a)
Kết quả:
True
Nếu dữ liệu là List thì Python sẽ tìm tuần tự.
Nếu dữ liệu là Set hoặc Dictionary thì Python sẽ dùng Hash Search.
Ví dụ:
a = [5, 8, 10, 13] print(a.index(10))
Kết quả:
2
Bên trong, hàm index() cũng sử dụng Linear Search.
| Thuật toán | Cần sắp xếp? | Độ phức tạp | Khi nào dùng? |
|---|---|---|---|
| Linear Search | Không | O(n) | Dữ liệu nhỏ hoặc chưa sắp xếp |
| Binary Search | Có | O(log n) | Dữ liệu đã sắp xếp |
| Jump Search | Có | O(√n) | Dữ liệu lớn, ít sử dụng |
| Interpolation Search | Có | O(log log n) | Dữ liệu phân bố đều |
| Tree Search | Cây cân bằng | O(log n) | Dữ liệu lưu trong cây |
| Hash Search | Không | O(1) | Tra cứu nhanh theo khóa |
Các thuật toán tìm kiếm (Search Algorithms)