Dưới đây là một số mã giả gần hơn với những gì thực sự xảy ra. Hãy tưởng tượng từ điển có thuộc tính data
chứa các cặp khóa, giá trị và size
là số lượng ô được phân bổ.
def lookup(d, key):
perturb = j = hash(key)
while True:
cell = d.data[j % d.size]
if cell.key is EMPTY:
raise IndexError
if cell.key is not DELETED and (cell.key is key or cell.key == key):
return cell.value
j = (5 * j) + 1 + perturb
perturb >>= PERTURB
Giá trị perturb
đảm bảo rằng tất cả các bit của mã băm được cuối cùng được sử dụng khi giải quyết xung đột băm nhưng một khi nó đã bị chuyển hóa thành 0 các (5*j)+1
cuối cùng sẽ chạm vào tất cả các ô trong bảng.
size
luôn lớn hơn số lượng ô thực tế được sử dụng để băm được đảm bảo cuối cùng sẽ nhấn vào ô trống khi khóa không tồn tại (và thường sẽ chạm nhanh). Ngoài ra còn có một giá trị đã xóa cho một khóa để biểu thị một ô không nên chấm dứt tìm kiếm nhưng hiện không được sử dụng.
Đối với câu hỏi của bạn về độ dài của chuỗi khóa, băm chuỗi sẽ xem xét tất cả các ký tự trong chuỗi, nhưng một chuỗi cũng có trường được sử dụng để lưu trữ băm được tính. Vì vậy, nếu bạn sử dụng các chuỗi khác nhau mỗi lần để thực hiện tra cứu, độ dài chuỗi có thể có vòng bi, nhưng nếu bạn có một bộ khóa cố định và sử dụng lại các chuỗi giống nhau thì hàm băm sẽ không được tính lại sau lần đầu tiên nó được sử dụng . Python nhận được lợi ích từ điều này vì hầu hết các tra cứu tên đều liên quan đến từ điển và một bản sao của mỗi biến hoặc tên thuộc tính được lưu trữ nội bộ, vì vậy mỗi khi bạn truy cập một thuộc tính x.y
có tra cứu từ điển nhưng không gọi hàm băm.
Trong khi tôi có thể xem các từ điển python sẽ hoạt động như được mô tả bên dưới, các hash nói chung phong phú hơn thế này. Người ta có thể tưởng tượng rằng tra cứu đơn giản này sẽ mất một thời gian dài với một từ điển lớn. Perl hashes sử dụng một hệ thống cơ bản là một chỉ mục bằng cách gộp các phần tử băm bởi mỗi ký tự của khóa. – shigeta
xem http://www.perl.com/pub/2002/10/01/hashes.html – shigeta