Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 17 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
17
Dung lượng
348,24 KB
Nội dung
Bảng băm (Hash Tables) Nguyễn Mạnh Hiển hiennm@tlu.edu.vn Bảng băm • Các phần tử dạng cặp khóa-giá trị (key-value) • Mỗi phần tử lưu trữ vào ô mảng tùy theo khóa • Thực phép tìm/chèn/xóa thời gian O(1) • Khơng hiệu với thao tác địi hỏi thơng tin thứ tự: − VD: Tìm phần tử lớn nhỏ Ví dụ bảng băm Mỗi phần tử cặp khóa-giá trị: - Tên khóa - Thu nhập giá trị So sánh cấu trúc liệu • So sánh thời gian tìm kiếm: − Vector danh sách liên kết: O(n) − Cây AVL: O(log n) − Bảng băm: O(1) Hàm băm (hash function) • Ánh xạ khóa sang số ngun (vị trí bảng băm) • Nếu nhiều khóa ánh xạ sang số nguyên (cùng vị trí bảng băm) dẫn đến đụng độ: − Đụng độ giảm khóa phân bố đồng bảng băm − Khi đụng độ xảy ra, phải tìm cách phân giải cho phần tử khơng ghi đè lên Một hàm băm đơn giản • Gọi: − key: Khóa có giá trị nguyên − tableSize: Kích thước bảng băm • Một hàm băm đơn giản dùng phép chia lấy phần dư: hash(key) = key % tableSize • Giả sử: − key = 24, 48, 51, 78, 15 − tableSize = 10 • Thế thì: key % tableSize = 4, 8, 1, 8, • Để giảm đụng độ, ta thường chọn kích thước bảng số nguyên tố Một hàm băm cho xâu ký tự int hash(const string & key, int tableSize) { int hashVal = 0; for (int i = 0; i < key.size(); i++) hashVal += key[i]; return hashVal % tableSize; } • Ví dụ: − tableSize = 100 − key = "ABC" (mã ASCII A, B, C 65, 66, 67) − hashVal = (65 + 66 + 67) % 100 = 198 % 100 = 98 − Nếu key = "CBA" hashVal = ? • Một hàm băm tốt cho xâu ký tự key = x0x1 xk-2xk-1 sau: hash(key) = (x0*ak−1 + x1*ak−2 + ··· + xk−2*a + xk−1) % tableSize − Nếu xâu ký tự từ tiếng Anh, chọn a = 33, 37, 39 41 Thiết kế bảng băm Hàm băm: Ánh xạ khóa sang vị trí bảng băm − VD: hash(key) = key % tableSize Phân giải đụng độ: − Giải trường hợp nhiều khóa ánh xạ đến vị trí − Hai giải pháp thường gặp: • Dây chuyền (separate chaining) • Thăm dị (probing) Giải pháp dây chuyền • Mỗi mảng giữ danh sách liên kết phần tử (dây chuyền) • Các phần tử có khóa ánh xạ tới ô giữ danh sách liên kết • Ví dụ: – hash(key) = key % 10 – Chèn 10 số phương vào bảng băm (hình bên) Phân tích giải pháp dây chuyền • Xét bảng băm có m chứa n phần tử • Chèn khơng kiểm tra tính thời gian O(1), gồm bước: Tìm vị trí chèn dùng hàm băm: O(1) Gọi pushFront danh sách liên kết: O(1) • Tìm/xóa/chèn có kiểm tra tính nhất, trường hợp tồi (phải quét hết danh sách liên kết có n phần tử): O(n) • Tìm/xóa/chèn có kiểm tra tính nhất, trường hợp trung bình: O(n/m) – Ta tăng kích thước bảng số phần tử trung bình ô (n/m) vượt hệ số tải (≤ 1) – Do đó, thời gian trung bình = O() = O(1) Bảng băm thăm dị • Bảng băm dây chun phức tạp phải trì danh sách liên kết • Giải pháp thăm dị trống: − Nếu đụng độ xảy ra, thử ô khác bảng − Thử ô h0(x), h1(x), h2(x), h3(x)… tìm trống: • hi(x) = [hash(x) + f(i)] % tableSize • f(0) = (vì ta bắt đầu thăm dị từ vị trí thu sau áp dụng phép băm) Thăm dị tuyến tính hi(x) = [hash(x) + f(i)] % tableSize, f(i) = i • Phép chèn (giả sử khóa khơng trùng nhau): index = hash(x); Nếu table[index] rỗng, đặt phần tử (gồm khóa giá trị) vào ô table[index]; Nếu table[index] không rỗng: – index++; index = index % tableSize; – Quay lại bước 2; • Tìm kiếm: index = hash(x); Nếu table[index] rỗng, trả -1 (khơng tìm thấy); Nếu table[index].key == x, trả index (tìm thấy); index++; index = index % tableSize; quay lại bước 2; Ví dụ Chèn 89, 18, 49, 58, 69 (hash(x) = x % 10) Thăm dò bậc hai hi(x) = [hash(x) + f(i)] % tableSize, f(i) = i2 Tổ chức lại bảng băm • Nếu bảng băm đầy, khơng thể chèn thêm • Nếu bảng băm đầy (nhưng chưa đầy 100%), chèn/xóa tìm kiếm nhiều thời gian • Giải pháp tổ chức lại bảng băm: Tạo bảng có kích thước lớn (VD: gấp hai lần) Định nghĩa hàm băm Chuyển phần tử từ bảng cũ sang bảng Xóa bảng cũ • Chi phí tổ chức lại bảng băm O(n): − Khá tốn xảy không thường xuyên − Chỉ xảy bảng băm vượt hệ số tải Ví dụ tổ chức lại bảng băm thăm dị tuyến tính Bảng băm ban đầu Chèn thêm 23 Tổ chức lại bảng băm (giả sử = 0.7) ‒ Gấp đơi kích thước cũ tìm số nguyên tố (ở 17) để dùng làm kích thước ‒ Quét bảng băm cũ từ đầu đến cuối để lấy giá trị chèn vào bảng theo thứ tự lấy Bài tập Xét bảng băm rỗng có hàm băm hash(x) = x % 10 Hãy chèn vào bảng giá trị { 4371, 1323, 6173, 4199, 4344, 9679, 1989 } cho trường hợp sau: (a) Bảng băm dây chuyền (b) Bảng băm thăm dị tuyến tính (c) Bảng băm thăm dị bậc hai Hãy tổ chức lại bảng băm sau chèn tập cho kích thước bảng băm gấp đôi ... i2 Tổ chức lại bảng băm • Nếu bảng băm đầy, khơng thể chèn thêm • Nếu bảng băm đầy (nhưng chưa đầy 100%), chèn/xóa tìm kiếm nhiều thời gian • Giải pháp tổ chức lại bảng băm: Tạo bảng có kích thước... hàm băm Chuyển phần tử từ bảng cũ sang bảng Xóa bảng cũ • Chi phí tổ chức lại bảng băm O(n): − Khá tốn xảy không thường xuyên − Chỉ xảy bảng băm vượt hệ số tải Ví dụ tổ chức lại bảng băm thăm... chèn vào bảng theo thứ tự lấy Bài tập Xét bảng băm rỗng có hàm băm hash(x) = x % 10 Hãy chèn vào bảng giá trị { 4371, 1323, 6173, 4199, 4344, 9679, 1989 } cho trường hợp sau: (a) Bảng băm dây