Phép băm là một bài toán cổ điển của khoa học máy tính, đã có nhiều thuật toán khác nhau được nghiên cứu và được dùng rất rộng rãi. Có một số lượng lớn những phân tích và kinh nghiệm để cung cấp các thủ tục băm cho rất nhiều ứng dụng khác nhau. Hàm băm một hàm mạnh trong mã hóa, chữ kí điện từ, xác nhận tính toàn vẹn của thông điệp…Phép băm là một thí dụ tốt về vấn đề dung hoà giữa thời gian chạy và dung lượng bộ nhớ sử dụng. Nếu không có sự giới hạn về bộ nhớ thì chúng ta có thể thực hiện bất kỳ một thao tác tìm kiếm nào chỉ với một lần truy xuất bộ nhớ bằng cách sử dụng khoá như một địa chỉ bộ nhớ. Nếu không có sự giới hạn về thời gian thì chúng ta có thể tối thiểu hoá dung lượng sử dụng bộ nhớ bằng cách dùng một phương pháp tìm kiếm tuần tự. Phép băm cung cấp một phương pháp dùng một lượng vừa phải của bộ nhớ và để làm một sự cân bằng giữa hai thái cực này. Sử dụng hiệu quả bộ nhớ có sẵn và truy xuất nhanh đến bộ nhớ là quan tâm chủ yếu của bất kỳ một phương pháp băm. Phép băm đưa ra một cách tiếp cận đầy đủ tới việc tìm kiếm khác hẳn với việc tìm kiếm đã biết như tìm kiếm trên cấu trúc cây…
Trang 1MỞ ĐẦU
1 LÝ DO, MỤC ĐÍCH CHỌN ĐỀ TÀI
Phép băm là một bài toán cổ điển của khoa học máy tính, đã có nhiều thuật toánkhác nhau được nghiên cứu và được dùng rất rộng rãi Có một số lượng lớn nhữngphân tích và kinh nghiệm để cung cấp các thủ tục băm cho rất nhiều ứng dụng khácnhau Hàm băm một hàm mạnh trong mã hóa, chữ kí điện từ, xác nhận tính toàn vẹncủa thông điệp…
Phép băm là một thí dụ tốt về vấn đề dung hoà giữa thời gian chạy và dung lượng
bộ nhớ sử dụng Nếu không có sự giới hạn về bộ nhớ thì chúng ta có thể thực hiện bất
kỳ một thao tác tìm kiếm nào chỉ với một lần truy xuất bộ nhớ bằng cách sử dụng khoánhư một địa chỉ bộ nhớ Nếu không có sự giới hạn về thời gian thì chúng ta có thể tốithiểu hoá dung lượng sử dụng bộ nhớ bằng cách dùng một phương pháp tìm kiếm tuần
tự Phép băm cung cấp một phương pháp dùng một lượng vừa phải của bộ nhớ và đểlàm một sự cân bằng giữa hai thái cực này Sử dụng hiệu quả bộ nhớ có sẵn và truyxuất nhanh đến bộ nhớ là quan tâm chủ yếu của bất kỳ một phương pháp băm Phépbăm đưa ra một cách tiếp cận đầy đủ tới việc tìm kiếm khác hẳn với việc tìm kiếm đãbiết như tìm kiếm trên cấu trúc cây… Do đó phương pháp băm là phương pháp rất
hiệu quả để cài đặt từ điển Chính vì vậy đề tài “ứng dụng bảng băm trong từ điển”
được thực hiện nhằm giới thiệu về kỹ thuật băm và tìm hiểu ứng dụng quan trọng của
nó trong từ điển
Có thể lập được một chương trình viết bằng ngôn ngữ Java giúp người học có thểtra cứu được từ điển Anh-Việt
Trang 22 MỤC TIÊU CẦN ĐẠT ĐƯỢC CỦA ĐỀ TÀI
Đề tài này được thực hiện nhằm đạt được mục tiêu là hiểu rõ, sâu sắc hơn về phépbăm, các hàm băm Tìm hiểu ứng dụng quan trọng của nó trong ứng dụng tìm kiếm từtrong từ điển
5 PHƯƠNG PHÁP NGHIÊN CỨU
- Tìm hiểu thông tin trên mạng internet, sách, báo, tạp chí…
- Thông qua sự hướng dẫn của thầy cô giáo và nghiên cứu những tài liệu tham khảoliên quan
6 CẤU TRÚC ĐỀ TÀI
- Mở đầu
- Chương I: Tìm hiểu sơ lược về kĩ thuật băm
- Chương II: Ứng dụng bảng băm trong từ điển
- Kết luận
Trang 3CHƯƠNG I: KĨ THUẬT BĂM
1.1 TÌM HIỂU KĨ THUẬT BĂM
1.1.1 Giới thiệu
Phép băm được đề xuất và hiện thực trên máy tính từ những năm 50 của thế kỷ
XX Nó dựa trên ý tưởng: biến đổi giá trị khóa thành một số (xử lý băm) và sử dụng sốnày để đánh chỉ cho bảng dữ liệu
Các phép toán trên các cấu trúc dữ liệu như danh sách, cây nhị phân,… phần lớnđược thực hiện bằng cách so sánh các phần tử của cấu trúc, do vậy thời gian truy xuấtkhông nhanh và phụ thuộc vào kích thước của cấu trúc
Chúng ta sẽ khảo sát một cấu trúc dữ liệu mới được gọi là bảng băm (hash table).Các phép toán trên bảng băm sẽ giúp hạn chế số lần so sánh, và vì vậy sẽ cố gắng giảmthiểu được thời gian truy xuất Độ phức tạp của các phép toán trên bảng băm thường cóbậc là O(1) và không phụ thuộc vào kích thước của bảng băm
* PHÉP BĂM (Hash Function)
Trong hầu hết các ứng dụng, khoá được dùng như một phương thức để truy xuất
dữ liệu Hàm băm được dùng để ánh xạ giá trị khóa vào một dãy các địa chỉ của bảng băm(hình 1)
Trang 4bản ghi ấy Như vậy nghĩa là ta thiết lập một hàm băm h(k) thực hiện phép ánh xạ tập cácgiá trị của k lên tập các địa chỉ tương đối, nghĩa là các số nguyên từ 0 đến m-1 mà ta gọi
là bảng địa chỉ, m được gọi là độ dài hay kích thước của bảng Như vậy ta luôn có: 0
≤ h(k) < m Giá trị của h(k) sẽ được sử dụng khi lưu trữ cũng như khi tìm kiếm bản ghiứng với k
Giá trị khóa Địa chỉ5402
037612462983
402367246983
Khi lưu trữ bản ghi ứng với khóa chẳng hạn 5042 sẽ được đưa vào một ô gồm một
số byte trong bộ nhớ thực có địa chỉ là A0 + 402 Đến khi tìm kiếm thì địa chỉ A0 + 402 lạiđược xác định để sử dụng Để tiện trình bày ta coi địa chỉ A0 = 0 nghĩa là tạm thời coi địachỉ tương đối như địa chỉ thực
Rõ ràng với phương pháp này các khóa có giá trị khác nhau cũng có thể cùng ứngvới một địa chỉ, ví dụ 5402, 7402, 0402 đều cùng một địa chỉ 402 Lúc đó ta nói hiệntượng đụng độ (collision)
Trang 5* Một hàm băm tốt phải thõa mãn các điều kiện sau:
Tất nhiên với phương pháp này, có thể có một số giá trị nào đó của m tạo ra đượch(k) tốt hơn giá trị khác của nó Ví dụ nếu m là số chẵn thì h(k) sẽ chẵn khi k chẵn, lẻ khi
k lẻ, như vậy với giá trị m này h(k) sẽ không được ngẫu nhiên lắm Trường hợp m là luỹthừa của cơ số của hệ đếm đang dùng, ví dụ như đối với hệ đếm thập phân mà m = 1000như trên thì cũng không tốt vì lúc này h(k) chính là con số bao gồm các chữ số ở bên phảicủa khoá không có ảnh hưởng gì tới h(k) cả, do đó đối với các giá trị khoá mà chỉ khácnhau ở các chữ số nằm bên trái sẽ xảy ra hiện tượng đụng độ
Thông thường người ta chọn m* là số nguyên tố nhỏ hơn và gần m thay cho m,nghĩa là lúc này h(k) = k mod m* Như ví dụ trên nếu m* = 997 ta sẽ có kết quả:
Giá trị khoá Địa chỉ5402
036712462983
417367249989
Trang 6Bây giờ nếu có thêm các khoá 7402, 0402 thì địa chỉ băm tương ứng của chúng là 423,
402 nghĩa là không trùng với địa chỉ 417 tương ứng với khoá 5402 ở trên
Phương pháp này là một trong những phương pháp đơn giản khá phổ dụng
170 hoặc 708
100 hoặc 006
789 hoặc 896
1.2.3 Phương pháp phân đoạn
Nếu khoá có kích thước lớn, kích thước thay đổi thì người ta áp dụng phương phápphân đoạn Trước hết giá trị khoá phân thành nhiều đoạn khác nhau (có thể trừ đoạn đầuhoặc đoạn cuối) thường mỗi đoạn có độ dài bằng độ dài địa chỉ Muốn vậy người ta ápdụng các kỹ thuật như:
Trang 7a) Tách (spliting): tách các đoạn ra, xếp mỗi đoạn một hàng, dóng thẳng theo đầutrái hoặc đầu phải.
b) Gấp (folding): gấp các đoạn lại theo đường biên tương tự như gấp giấy Các chữ
số rơi vào cùng một chỗ được đặt thành hàng dóng thẳng với nhau
Sau khi các đoạn đã được tách hoặc gấp chúng sẽ được phối hợp với nhau theo mộtcách nào đấy Ví dụ chúng được cộng lại Từ kết quả thu được lấy một đoạn dài bằng địachỉ để làm địa chỉ băm hoặc lại áp dụng với nó các kỹ thuật tạo địa chỉ như đã nêu Giả sử
có khoá: 17046329 Bằng phương pháp phân tách ta phân ra các đoạn 3 chữ số kể từ đầuphải rồi cộng lại Ta có:
329
046017392
392 được coi là địa chỉ băm ứng với khoá đó
Còn bằng phương pháp gấp ta sẽ có:
0469237101679
Ta có thể lấy 167 hoặc 679 làm địa chỉ băm
Với phương pháp này ta cũng thấy các chữ số của khoá đều được tham gia vào việc tạonên địa chỉ băm tương ứng với nó
1.2.4 Hàm băm cho các giá trị khoá là xâu ký tự
Để băm các xâu ký tự, trước hết chúng ta chuyển đổi các xâu ký tự thành các sốnguyên Các ký tự trong bảng mã ASCII gồm 128 ký tự được đánh số từ 0 đến 127, do đómột xâu ký tự có thể xem như một số trong hệ đếm cơ số 128 Áp dụng phương pháp
Trang 8chuyển đổi một số trong hệ đếm bất kỳ sang một số trong hệ đếm cơ số 10, chúng ta sẽchuyển đổi được một xâu ký tự thành một số nguyên Chẳng hạn, xâu “NOTE” đượcchuyển thành một số nguyên như sau:
= 78.1283 + 79.1282 + 84.128 + 69Vấn đề nảy sinh với cách chuyển đổi này là, chúng ta cần tính các luỹ thừa của
128, với các xâu ký tự tương đối dài, kết quả nhận được sẽ là một số nguyên cực lớn vượtquá khả năng biểu diễn của máy tính
Trong thực tế, thông thường một xâu ký tự được tạo thành từ 26 chữ cái và 10 chữ
số, và một vài ký tự khác Do đó chúng ta thay 128 bởi 37 và tính số nguyên ứng với xâu
ký tự theo luật Horner Chẳng hạn, số nguyên ứng với xâu ký tự “NOTE” được tính nhưsau:
= ((78.37 + 79).37 +84).37 +69
Sau khi chuyển đổi xâu ký tự thành số nguyên bằng phương pháp trên, chúng ta sẽ
áp dụng phương pháp chia để tính giá trị băm Hàm băm các xâu ký tự được cài đặt nhưsau (ngôn ngữ C++):
unsigned int hash(const string &k, int N)
{
unsigned int value = 0;
for (int i=0; i< k.length(); i++)
value = 37 * value + k[i];
return value % N;
}
Trang 91.2.5 Bảng băm
1.2.6.1 Mô tả dữ liệu
Tập khoá k Hàm băm h Tập địa chỉ M
Giả sử:
k: là tập các khoá (set of keys)
M: tập địa chỉ (set of addresses)
h(k): hàm băm dùng để ánh xạ một khoá k từ tập các khoá k thành một địa chỉtương ứng trong tập M
1.2.6.2 Các phép toán trên bảng băm
- Khởi tạo (initialize): khởi tạo bảng băm, cấp phát vùng nhớ hay quy định số phần
tử (kích thước) của bảng băm
- Kiểm tra rỗng (empty): kiểm tra bảng băm có rỗng hay không?
- Tìm kiếm (search): tìm kiếm một phần tử trong bảng băm theo khoá k chỉ địnhtrước
- Thêm một phần tử mới (insert): thêm một phần tử vào bảng băm Sau khi thêm sốphần tử của bảng băm tăng thêm một đơn vị
- Loại bỏ (remove): loại bỏ một phần tử khỏi bảng băm, số phần tử sẻ giảm đi một
Trang 101.2.6.3 Các bảng băm thông dụng
Với mỗi loại bảng băm cần thiết phải xác định tập khoá k, xác định tập địa chỉ M
và xây dựng hàm băm h cho phù hợp
a Bảng băm với phương pháp kết nối trực tiếp (bảng băm dây chuyền): mỗi địa
chỉ của bảng băm tương ứng một danh sách liên kết Các phần tử được kết nối với nhautrên một danh sách liên kết
b Bảng băm với phương pháp kết nối hợp nhất: bảng băm này được cài đặt bằng
danh sách kề, mỗi phần tử có hai trường: trường key chứa khoá của phần tử và trườngnext chứa phần tử kế bị xung đột, các phần tử được kết nối với nhau qua trường kết nốinext
c Bảng băm với phương pháp dò tuần tự: khi thêm phần tử vào bảng băm nếu bị
đụng độ thì sẽ dò địa chỉ kế tiếp… cho đến khi gặp địa chỉ trống đầu tiên thì thêm phần tửvào địa chỉ này
d Bảng băm với phương pháp dò bậc hai: ví dụ khi thêm phần tử vào bảng băm
này, nếu băm lần đầu bị xung đột thì sẽ dò đến địa chỉ mới, ở lần dò thứ i sẽ xét phần tửcách i 2 cho đến khi gặp địa chỉ trống đầu tiên thì thêm phần tử vào địa chỉ này
e Bảng băm với phương pháp băm kép: bảng băm này dùng hai hàm băm khác
nhau, băm lần đầu với hàm băm thứ nhất nếu bị xung đột thì xét địa chỉ khác bằng hàmbăm thứ hai
f Bảng băm với phương pháp dò tuyến tính: Nếu băm lần đầu bị xung đột thì băm
lại lần một, nếu bị xung đột nữa thì băm lại lần hai, quá trình băm lại diễn ra cho đếnkhi không còn xung đột nữa Các phép băm lại thường sẽ chọn các địa chỉ khác cho cácphần tử
1.3 GIẢI QUYẾT ĐỤNG ĐỘ
Một cách tiếp cận đầy đủ tới việc tìm kiếm khác với tìm kiếm trên cấu trúc cây làphép băm: một phương pháp tham chiếu trực tiếp đến các mẩu tin bằng cách thực hiện cácphép chuyển đổi số học từ các khoá vào các địa chỉ bảng Nếu chúng ta biết rằng các khoá
Trang 11là các số nguyên phân biệt từ 1 đến N thì chúng ta có thể lưu mẩu tin với khoá i trong vịtrí i của bảng, chuẩn bị để truy xuất tức thời nhờ vào giá trị khoá Phép băm là sự tổngquát hoá của phương pháp tầm thường này cho các ứng dụng tìm kiếm thông thường khichúng ta không có sự hiểu biết đặc biệt về khoá (chưa có thông tin cụ thể về các giá trịkhoá).
Bước đầu tiên của việc tìm kiếm bằng phép băm là tính một hàm băm (hashfunction) để chuyển đổi từ khoá tìm kiếm vào địa chỉ bảng Trong trường hợp lý tưởngcác khoá khác nhau nên ánh xạ vào các địa chỉ khác nhau nhưng thực tế thì không có hàmbăm hoàn chỉnh và sẽ có 2 hay nhiều khoá khác nhau băm đến cùng một địa chỉ Phần thứhai của tìm kiếm băm là giải quyết xung đột (collision-resolution) để cư xử với các khoánhư đã nói Một trong những phương pháp xử lý xung đột mà chúng ta nghiên cứu làdùng các danh sách liên kết, bởi vì lưu trữ động nên phương pháp này thích hợp khi sốlượng khoá tìm kiếm không thể tiên đoán trước Hai phương pháp xử lý xung đột khác màchúng ta xem xét sẽ có thời gian tìm kiếm nhanh trên các mẩu tin được lưu trữ trên mộtmảng cố định
Trong mục này chúng ta sẽ trình bày hai phương pháp giải quyết va chạm Trongphương pháp thứ nhất, mỗi khi xảy ra va chạm, chúng ta tiến hành thăm dò để tìm một vịtrí còn trống trong bảng và đặt dữ liệu mới vào đó Một phương pháp khác là, chúng ta tạo
ra một cấu trúc dữ liệu lưu giữ tất cả các dữ liệu được băm vào cùng một vị trí trong bảng
và “gắn” cấu trúc dữ liệu này vào vị trí đó trong bảng
mở (open addressing)
Trang 12Giả sử vị trí mà hàm băm xác định ứng với khoá k là i, i = h(k) Từ vị trí này chúng
ta lần lượt xem xét các vị trí
i0 , i1 , i2 ,…, im ,…
Trong đó i0 = i, im (m=0,1,2,…) là vị trí thăm dò ở lần thứ m Dãy các vị trí này sẽđược gọi là dãy thăm dò Vấn đề đặt ra là, xác định dãy thăm dò như thế nào? Sau đâychúng ta sẽ trình bày một số phương pháp thăm dò và phân tích ưu khuyết điểm của mỗiphương pháp
1.3.1.1 Thăm dò tuyến tính
Đây là phương pháp thăm dò đơn giản và dễ cài đặt nhất Với khoá k, giả sử vị tríđược xác định bởi hàm băm là i = h(k), khi đó dãy thăm dò là
i , i+1, i+2 , …
Như vậy thăm dò tuyến tính có nghĩa là chúng ta xem xét các vị trí tiếp liền nhau
kể từ vị trí ban đầu được xác định bởi hàm băm Khi cần xen vào một dữ liệu mới vớikhoá k, nếu vị trí i = h(k) đã bị chiếm thì ta tìm đến các vị trí đi liền sau đó, gặp vị trí còntrống thì đặt dữ liệu mới vào đó
Ví dụ Giả sử cỡ của mảng N = 11 Ban đầu mảng T rỗng, và ta cần xen lần lượt
các dữ liệu với khoá là 388, 130, 13, 14, 926 vào mảng Băm khoá 388, h(388) = 3, vì vậy
388 được đặt vào T[3]; h(130) = 9, đặt 130 vào T[9]; h(13) = 2, đặt 13 trong T[2] Xéttiếp dữ liệu với khoá 14, h(14) = 3, xảy ra va chạm (vì T[3] đã bị chiếm bởi 388), ta tìmđến vị trí tiếp theo là 4, vị trí này trống và 14 được đặt vào T[4] Tương tự, khi xen vào
926 cũng xảy ra va chạm, h(926) = 2, tìm đến các vị trí tiếp theo 3, 4, 5 và 926 được đặtvào T[5] Kết quả là chúng ta nhận được mảng T như trong hình 3
Hình 3 Bảng băm sau khi xen vào các dữ liệu 388, 130, 13, 14 và 926
T
Trang 13Bây giờ chúng ta xét xem, nếu lưu tập dữ liệu trong mảng bằng phương pháp địnhđịa chỉ mở thì các phép toán tìm kiếm, xen, loại được tiến hành như thế nào Các kỹ thuậttìm kiếm, xen, loại được trình bày dưới đây có thể sử dụng cho bất kỳ phương pháp thăm
dò nào Trước hết cần lưu ý rằng, để tìm, xen, loại chúng ta phải sử dụng cùng mộtphương pháp thăm dò, chẳng hạn thăm dò tuyến tính Giả sử chúng ta cần tìm dữ liệu vớikhoá là k Đầu tiên cần băm khoá k, giả sử h(k)=i Nếu trong bảng ta chưa một lần nàothực hiện phép toán loại, thì chúng ta xem xét các dữ liệu chứa trong mảng tại vị trí i vàcác vị trí tiếp theo trong dãy thăm dò, chúng ta sẽ phát hiện ra dữ liệu cần tìm tại một vịtrí nào đó trong dãy thăm dò, hoặc nếu gặp một vị trí trống trong dãy thăm dò thì có thểdừng lại và kết luận dữ liệu cần tìm không có trong mảng Chẳng hạn chúng ta muốn tìmxem mảng trong hình 3 có chứa dữ liệu với khoá là 47? Bởi vì h(47) = 3, và dữ liệu đượclưu theo phương pháp thăm dò tuyến tính, nên chúng ta lần lượt xem xét các vị trí 3, 4, 5.Các vị trí này đều chứa dữ liệu khác với 47 Đến vị trí 6, mảng trống Vậy ta kết luận 47không có trong mảng Để loại dữ liệu với khoá k, trước hết chúng ta cần áp dụng thủ tụctìm kiếm đã trình bày ở trên để định vị dữ liệu ở trong mảng Giả sử dữ liệu được lưutrong mảng tại vị trí p Loại dữ liệu ở vị trí p bằng cách nào? Nếu đặt vị trí p là vị trítrống, thì khi tìm kiếm nếu thăm dò gặp vị trí trống ta không thể dừng và đưa ra kết luận
dữ liệu không có trong mảng Chẳng hạn, trong mảng hình 3, ta loại dữ liệu 388 bằngcách xem vị trí 3 là trống, sau đó ta tìm dữ liệu 926, vì h (926) = 2 và T[2] không chứa
926, tìm đến vị trí 3 là trống, nhưng ta không thể kết luận 926 không có trong mảng Thực
tế 926 ở vị trí 5, vì lúc đưa 926 vào mảng các vị trí 2, 3, 4 đã bị chiếm Vì vậy để đảm bảothủ tục tìm kiếm đã trình bày ở trên vẫn còn đúng cho trường hợp đã thực hiện phép toánloại, khi loại dữ liệu ở vị trí p chúng ta đặt vị trí p là vị trí đã loại bỏ Như vậy, chúng taquan niệm mỗi vị trí i trong mảng (0 <= i <= N-1) có thể là vị trí trống (EMPTY), vị trí đãloại bỏ (DELETED), hoặc vị trí chứa dữ liệu (ACTIVE) Đương nhiên là khi xen vào dữliệu mới, chúng ta có thể đặt nó vào vị trí đã loại bỏ Việc xen vào mảng một dữ liệu mớiđược tiến hành bằng cách lần lượt xem xét các vị trí trong dãy thăm dò ứng với mỗi khoá
Trang 14của dữ liệu, khi gặp một vị trí trống hoặc vị trí đã được loại bỏ thì đặt dữ liệu vào đó Sauđây là hàm thăm dò tuyến tính:
int Probing (int i, int m, int N)
1.3.1.2 Thăm dò bình phương
Để khắc phục tình trạng dữ liệu tích tụ thành từng cụm trong phương pháp thăm dòtuyến tính, chúng ta không thăm dò các vị trí kế tiếp liền nhau, mà thăm dò bỏ chỗ theomột quy luật nào đó Trong thăm dò bình phương, nếu vị trí ứng với khoá k là i =h(k), thì dãy thăm dò là:
i , i + 12, i + 22,… , i + m2,…
Ví dụ: Nếu cỡ của mảng N = 11, và i = h(k) = 3, thì thăm dò bình phương cho phép ta tìm
đến các địa chỉ 3, 4, 7, 1, 8 và 6
Phương pháp thăm dò bình phương 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 Tuy nhiên nhược điểm của nó là khôngcho phép ta tìm đến tất cả các vị trí trong mảng, chẳng hạn trong ví dụ trên, trong số 11 vị
Trang 15trí từ 0, 1, 2, …, 10, ta chỉ tìm đến các vị trí 3, 4, 7, 1, 8 và 6 Hậu quả của điều đó là,phép toán xen vào có thể không thực hiện được, mặc dầu trong mảng vẫn còn các vị tríkhông chứa dữ liệu Chúng ta có thể dễ dàng chứng minh được khẳng định sau đây:
Nếu cỡ của mảng là số nguyên tố, thì thăm dò bình phương cho phép ta tìm đếnmột nửa số vị trí trong mảng Cụ thể hơn là, các vị trí thăm dò h(k) = m2 (mode N) vớim=0, 1,…, N/2 là khác nhau
Từ khẳng định trên chúng ta suy ra rằng, nếu cỡ của mảng là số nguyên tố vàmảng không đầy quá 50% thì phép toán xen vào luôn luôn thực hiện
1.3.1.3 Băm kép
Phương pháp băm kép (double hashing) có ưu điểm như thăm dò bình phương làhạn chế được sự tích tụ dữ liệu thành cụm; ngoài ra nếu chúng ta chọn cỡ của mảng là sốnguyên tố, thì băm kép còn cho phép ta thăm dò tới tất cả các vị trí trong mảng Trongthăm dò tuyến tính hoặc thăm dò bình phương, các vị trí thăm dò cách vị trí xuất phát mộtkhoảng cách hoàn toàn xác định trước và các khoảng cách này không phụ thuộc vào khoá.Trong băm kép, chúng ta sử dụng hai hàm băm h1 và h2:
Hàm băm h1 đóng vai trò như hàm băm h trong các phương pháp trước, nó xácđịnh vị trí thăm dò đầu tiên
Hàm băm h2 xác định bước thăm dò
Điều đó có nghĩa là, ứng với mỗi khoá k, dãy thăm dò là:
Trang 16h1(k) = k % 11
h2(k) = 1 + (k % 7)
với k = 58, thì bước thăm dò là h2(58) = 1 + 2 = 3, do đó dãy thăm dò là: h1(58) = 3, 6, 9,
1, 4, 7, 10, 2, 5, 8, 0 còn với k = 36, thì bước thăm dò là h2(36) = 1 + 1 = 2, và dãy thăm
1.3.2 Phương pháp kết nối (phương pháp dây chuyền)
Một cách tiếp cận khác để giải quyết sự va chạm là chúng ta tạo một cấu trúc dữliệu để lưu tất cả các dữ liệu được băm vào cùng một vị trí trong mảng Cấu trúc dữ liệuthích hợp nhất là danh sách liên kết (dây chuyền) Khi đó mỗi thành phần trong bảng bămT[i], với i = 0, 1, …, N – 1, sẽ chứa con trỏ trỏ tới đầu một danh sách liên kết Cách giảiquyết va chạm như trên được gọi là phương pháp tạo dây chuyền (separated chaining).Lược đồ lưu tập dữ liệu trong bảng băm sử dụng phương pháp tạo dây chuyền được mô tảtrong hình 4
Trang 17Ưu điểm của phương pháp giải quyết va chạm này là số dữ liệu được lưu khôngphụ thuộc vào cỡ của mảng, nó chỉ hạn chế bởi bộ nhớ cấp phát động cho các dây chuyền.Bây giờ chúng ta xét xem các phép toán từ điển được thực hiện như thế nào Các phéptoán được thực hiện rất dễ dàng, để xen vào bảng băm dữ liệu khoá k, chúng ta chỉ cầnxen dữ liệu này vào đầu danh sách liên kết được trỏ tới bởi con trỏ T[h(k)] Phép toán xenvào chỉ đòi hỏi thời gian O(1), nếu thời gian tính giá trị băm h(k) là O(1) Việc tìm kiếmhoặc loại bỏ một dữ liệu với khoá k được quy về tìm kiếm hoặc loại bỏ trên danh sách liênkết T[h(k)] Thời gian tìm kiếm hoặc loại bỏ đương nhiên là phụ thuộc vào độ dài củadanh sách liên kết Để minh họa ta xét bảng băm có sau:
- Tập khóa K: tập số tự nhiên
- Tập địa chỉ M: gồm 10 địa chỉ (M={0, 1, …, 9}
- Hàm băm h(key) = key % 10
Hình 5 Bảng băm với phương pháp kết nối trực tiếp
Trang 18Hình trên minh họa bảng băm vừa mô tả Theo hình vẽ, bảng băm đã "băm" phần
tử trong tập khoá K theo 10 danh sách liên kết khác nhau, mỗi danh sách liên kết là mộtbucket:
· Bucket 0 gồm những phần tử có khóa tận cùng bằng 0
· Bucket i(i=0 | … | 9) gồm những phần tử có khóa tận cùng bằng i
· Khi khởi động bảng băm, con trỏ đầu của các bucket là NULL
Theo cấu trúc này, với tác vụ insert, hàm băm h(k) sẽ được dùng để tính địa chỉcủa khoá k, tức là xác định bucket chứa phần tử và đặt phần tử cần chèn vào bucket này
Với tác vụ search, hàm băm sẽ được dùng để tính địa chỉ và tìm phần tử trênbucket tương ứng
+ i=h(k) => thuộc danh sách thứ i
+ Tìm kiếm khoá k trên danh sách thứ i
Chúng ta có nhận xét rằng, dù giải quyết va chạm bằng cách thăm dò, hay giảiquyết va chạm bằng cách tạo dây chuyền, thì bảng băm đều không thuận tiện cho sự thựchiện các phép toán tập động khác, chẳng hạn phép toán Min (tìm dữ liệu có khoá nhỏnhất), phép toán DeleteMin (loại dữ liệu có khoá nhỏ nhất), hoặc phép duyệt dữ liệu