Xử lý đụng độ (collision)
Hàm băm có thể đưa hai khóa khác nhau vào cùng một ô — gọi là đụng độ (collision). Điều này không tránh được hoàn toàn. Bạn sẽ học hai cách xử lý kinh điển: nối chuỗi và dò địa chỉ mở.
1. Vì sao đụng độ là không tránh khỏi?
Có vô số khóa có thể (mọi chuỗi), nhưng bảng chỉ có hữu hạn ô. Theo nguyên lý chuồng bồ câu,
kiểu gì cũng có hai khóa băm ra cùng chỉ số. Ví dụ với hàm băm cộng mã ký tự, "an" và "na" cho
cùng tổng → cùng ô!
"an" ──▶ ô 2
"na" ──▶ ô 2 ← ĐỤNG ĐỘ!
Bảng băm tốt không loại bỏ đụng độ — nó xử lý đụng độ cho gọn.
2. Cách 1: Nối chuỗi (chaining)
Mỗi ô không giữ một mục, mà giữ một danh sách các mục cùng băm vào đó. Đụng độ → cứ thêm vào danh sách của ô đó.
ô 0: → None
ô 1: → None
ô 2: → [("an", 90)] → [("na", 70)] ← hai mục cùng ô, nối thành chuỗi
ô 3: → None
ô 4: → [("ba", 80)]
Tìm khóa: băm ra ô, rồi duyệt danh sách nhỏ trong ô đó để khớp đúng khóa.
3. Cách 2: Dò địa chỉ mở (open addressing)
Mỗi ô chỉ giữ một mục. Đụng độ → dò sang ô kế tiếp (vd ô+1, ô+2...) cho tới khi gặp ô trống.
Thêm "an" -> ô 2 (trong) -> dat o o 2
Thêm "na" -> ô 2 (ban!) -> thu o 3 (trong) -> dat o o 3
Tìm khóa: băm ra ô, nếu không khớp thì dò tiếp cùng quy luật cho tới khi gặp khóa hoặc ô trống.
4. So sánh hai cách
| Nối chuỗi (chaining) | Dò địa chỉ mở (open addressing) | |
|---|---|---|
| Mỗi ô giữ | một danh sách | một mục |
| Khi đụng độ | thêm vào list của ô | dò sang ô khác |
| Ưu | đơn giản, chịu tải cao tốt | tiết kiệm bộ nhớ, cache tốt |
| Nhược | tốn con trỏ/list phụ | xuống cấp nhanh khi bảng gần đầy |
Python
dict/setdùng open addressing (biến thể tinh vi). Nhiều ngôn ngữ khác dùng chaining. Cả hai đều cho O(1) trung bình nếu bảng không quá đầy (bài tiếp theo).
5. Code minh họa: bảng băm nối chuỗi tự xây
6. Mẫu nhận diện
- Đụng độ là bình thường — bảng băm sinh ra để xử lý nó, không phải tránh.
- Nhiều đụng độ vào một ô → ô đó tra cứu chậm dần (duyệt list dài / dò xa). Cần hàm băm rải đều + giữ bảng không quá đầy.
7. 🎮 Trò chơi: Hiểu đụng độ
8. Quiz kiểm tra nhanh
9. Hoàn thành
…☑️ Tiếp theo: 2.4.3 — Hệ số tải, rehash & độ phức tạp.