Upload
nhan-meo
View
33
Download
12
Embed Size (px)
DESCRIPTION
Bài giảng cấu trúc dữ liệu chương 5
Citation preview
Chương 5: Bảng băm(Hash table)
Mở đầu
Tìm kiếm tuyến tính: O(n)
Tìm kiếm nhị phân: O(log2n) Cần thực hiện nhiều phép so sánh giữa các phần tử,
thời gian truy xuất lâu và phụ thuộc vào kích thước của cấu trúc
Phương pháp băm(hashing) sẽ giúp hạn chế số lần so sánh
Phương pháp băm(hashing)
Phương pháp băm(hashing)
Mỗi dữ liệu có khóa k được lưu trữ tại T[h(k)]
h: hash function. h(k) là giá trị băm của khóa k
T: hash table
Phương pháp băm(hashing)
Vấn đề “va chạm” (collision)
2 khóa có thể được ánh xạ vào cùng chỉ số
Thiết kế 1 hàm băm tốt:
o Tính được dễ dàng và nhanh địa chỉ ứng với
mỗi khoá
o Đảm bảo ít xảy ra va chạm
Thiết kế phương pháp để giải quyết va
chạm khi nó xảy ra
Hàm băm(hash function)
Phương pháp chia h(k) = k mod m Ví dụ: m=12, k=100, h(k)=4
Lựa chọn kích cỡ m sao cho hạn chế xảy ra va chạm
1. Nếu m = 2p h(k) sẽ không phụ thuộc vào tất cả các bit của k Ví dụ và p = 6
2. m là số nguyên tố
Hàm băm(hash function)
Phương pháp nhân h(k) = m *(k *A mod 1) Trong đó, A là hằng số thực, 0 < A < 1 k *A mod 1 là phần thập phân của k*A
Chọn m và A m = 2p
A gần bằng 0.618033987 (Knuth)
Hàm băm(hash function)
Hàm băm cho các giá trị khoá là xâu ký tự
Cần chuyển đổi xâu kí tự thành số nguyên
Áp dụng các hàm băm với khóa là số nguyên để tìm giá trị băm
Phương pháp chuyển đổi
Cách 1: Cộng dồn mã ASCII của các kí tự trong xâu
Cách 2:
1
037*]1[
KeySize
i
iiKeySizeKey
Giải quyết “va chạm”
Định địa chỉ mở(Open Addressing)
Tạo dây chuyền(separated chaining)
Giải quyết “va chạm” – Open Addressing
Tiến hành thăm dò để phát hiện ra vị trí trống và đặt dữ liệu mới vào vị trí đó
Hàm băm phụ thuộc vào keys và số thăm dò
Dãy thăm dò
xác định dãy thăm dò như thế nào?
Giải quyết “va chạm” – Open Addressing
h(K,i) = (hash(K) + f(i)) mod m, trong đó f(0) = 0
f: chiến lược giải quyết va chạm
Giải quyết “va chạm” – Open Addressing
Phương pháp thăm dò
Thăm dò tuyến tính(linear probing)
Thăm dò bình phương(Quadratic probing)
Băm kép(Double hashing)
Thăm dò tuyến tính (linear probing)
f(i) =i
Các vị trí được thăm dò 1 cách tuyến tính
h(K,i) = (hash(K) + i) mod m
Chèn dữ liệu
B1: tính hash(K)
B2: For i = 0 to m-1
L = ( hash(K) + i ) mod m
Nếu T[L] trống, thì đặt K vào vị trí L và dừng.
nếu không thể tìm vị trí trống bảng băm đã đầy cần báo lỗi, không chèn được
Thăm dò tuyến tính (linear probing)
Ví dụ: chèn các khóa 89, 18, 49, 58, 69 with hash(K)=K mod 10
Để chèn 58, dãy thăm dò: T[8], T[9], T[0], T[1]
Để chèn 69, dãy thăm dò: T[9], T[0], T[1], T[2]
Thăm dò tuyến tính (linear probing)
Ưu điểm:
Đơn giản dễ thực hiện
Xem xét được tất cả các vị trí trong mảng xác
suất chèn được dữ liệu lớn
Nhược điểm:
Các dữ liệu tập trung thành từng đoạn(cluster)
hiệu suất chèn phần tử mới sẽ giảm
tìm kiếm dữ liệu với khóa K không hiệu quả
Thăm dò bình phương (Quadratic probing)
h(K,i) = (hash(K) + i2) mod m
Nếu m là số nguyên tố và mảng không đầy quá 50% luôn chèn được dữ liệu thành công
Ưu điểm:
Tránh được sự tích tụ dữ liệu thành từng đoạn và tránh được sự tìm kiếm tuần tự trong các đoạn
Nhược điểm:
Không tìm được tất cả các vị trí có thể không
chèn được
Nếu hash(k1) = hash(k2) h(k1, i) = h(k2, i)
Băm kép(Double hashing)
Sử dụng 2 hàm băm
h(k, i) = (hash(k) + i*hash2(k)) MOD m
hash2(k): xác định bước thăm dò, hash2(k) 0
Có thể chọn hash2(K) = R - (K mod R)
Trong đó R - là số nguyên tố < m
Băm kép(Double hashing)
Ví dụ: m=10, R = 7 chèn các dữ liệu 89, 18, 49, 58, 69
hash2(49)=7, chèn 49 vào (9+7) mod 10
hash2(58)=5, chèn 58 vào (8+5) mod 10
hash2(69)=1, chèn 69 vào (9+1) mod 10
Giải quyết “va chạm” – Open Addressing
Tìm kiếm dữ liệu với khóa K
Tính hash(k)
Xem xét dữ liệu chứa trong mảng tại vị trí h(k) và các vị trí tiếp theo trong dãy thăm dò
Nếu gặp 1 vị trí trống dữ liệu không có và dừng
Ngược lại tìm tiếp cho đến khi tìm thấy
Xóa dữ liệu với khóa K
Search(K), nếu gặp vị trí trống không thể kết luận là dữ liệu không có
Kí hiệu mỗi vị trí trong mảng có thể là empty, deleted, active
Giải quyết “va chạm” - tạo dây chuyền
Sử dụng DSLK để lưu tất cả các dữ liệu của các khóa được băm vào cùng 1 vị trí
h(K) = K mod 10
Giải quyết “va chạm” - tạo dây chuyền
Chèn 1 dữ liệu với khóa K
Tính h(K)
Nếu T[h(K)] chứa con trỏ NULL khởi tạo DSLK
chứa dữ liệu của khóa K
Ngược lại, chèn vào đầu DSLK
Xóa 1 dữ liệu với khóa K
Tính h(K)
search(K) trong DSLK tại T[h(k)].
Delete K
Hiệu quả của phương pháp băm
Mức độ đầy (load factor).
Trong đó, N là số dữ liệu trong bảng
Khi tăng xác suất xảy ra va chạm sẽ tăng thời gian
tìm kiếm sẽ tăng.
Cần chọn m sao cho đủ nhỏ, < 2/3
m
N