Apakah mungkin untuk mempercepat tabel hash dengan menggunakan pohon pencarian biner untuk rantai terpisah?

11

Saya ingin menerapkan Tabel Hash menggunakan Pohon Pencarian Biner untuk mengurangi kompleksitas pencarian dalam proses Chaining Terpisah dari O (n) (menggunakan daftar tertaut) ke O (log n) (menggunakan BST). Bisakah ini dilakukan, dan jika ya lalu bagaimana? Akan lebih mudah untuk memahami jika solusi adalah langkah demi langkah, implementasi dari logika.

Saya ingin mengurangi waktu pencarian di hashtable (build menggunakan chaining terpisah), tetapi pada saat yang sama saya tidak ingin waktu insert meningkat. Untuk proyek saya, saya tidak dapat mengubah fungsi hash untuk mengurangi tabrakan. Tetapi karena skalabilitas, tabrakan terjadi. Saya mencoba mencari kerja di sekitar, sehingga saya entah bagaimana dapat bekerja dengan akses terbaik dan memasukkan waktu jika terjadi tabrakan ... yaitu untuk mengelola keadaan saat ini daripada untuk merestrukturisasi seluruh algoritma. Jika tidak berjalan maka harus merestrukturisasi. Jadi, ada ide?

Aviral
sumber
4
Tabel hash dan Pohon Pencarian Biner adalah wadah yang berbeda . Jadi Anda tidak bisa melakukan apa yang Anda sarankan (atau Anda membuat kesalahan terminologis).
Basile Starynkevitch
Saya kira Anda bisa menempatkan pasangan hash / nilai di setiap node di pohon ... tapi itu bisa berupa tabel hash yang buruk atau pohon biner yang buruk. Tanpa beberapa klarifikasi tentang mengapa Anda ingin melakukan ini sama sekali dan apa yang Anda inginkan dari hasil akhirnya, saya tidak yakin ini benar-benar dapat dijawab.
Ixrec
1
@AK_: Yup sesuatu seperti itu, seperti yang Anda katakan. saya ingin menangani tabrakan menggunakan pohon pencarian biner. saya sedikit mengoreksi pertanyaan saya untuk membuatnya lebih jelas.
Aviral
1
Catatan yang datang dengan penalti O (n log n) untuk setiap sisipan kemudian. Secara umum, ketika Anda memiliki tabel hash yang mulai menjadi terlalu penuh (dan Anda memiliki rantai lebih lama daripada yang bisa Anda toleransi), Anda membangun kembali hash. Jika Anda secara teratur menemukan rantai lebih dari 3 atau 4, ada sesuatu yang salah.
3
Ada banyak variasi pada tabel hash untuk pengurangan tabrakan, pengalamatan terbuka, dan pengubahan ukuran tabel secara dinamis. Yang mana yang sesuai dengan kebutuhan Anda adalah sesuatu yang harus Anda perhatikan. Pendekatan Anda saat ini dicakup dalam Chaining terpisah dengan struktur lain

Jawaban:

11

Apa yang Anda minta dimungkinkan karena kendala Anda.

Analisis

Kekuatan tabel hash adalah pencarian cepat dan kecepatan penyisipan. Untuk mendapatkan kecepatan itu, seseorang harus meninggalkan kemiripan urutan dalam tabel: yaitu entri semua tercampur. Daftar dapat diterima untuk digunakan sebagai entri tabel karena sementara traversal adalah O (n), daftar cenderung pendek dengan asumsi tabel hash cukup besar dan objek yang disimpan dalam tabel hash menggunakan algoritma hashing berkualitas baik.

Pohon pencarian biner (BST) memiliki penyisipan cepat dan pencarian di O (log 2 n). Ini juga memberlakukan pembatasan pada elemen yang disimpan: harus ada cara untuk memesan elemen. Mengingat dua elemen A dan B disimpan di pohon, harus mungkin untuk menentukan apakah A datang sebelum B atau jika mereka memiliki urutan yang setara.

Tabel hash tidak memberlakukan batasan seperti itu: elemen dalam tabel hash harus memiliki dua properti. Pertama, harus ada cara untuk menentukan apakah mereka setara; kedua, harus ada cara untuk menghitung kode hash deterministik. Pesanan bukan keharusan.

Jika elemen tabel hash Anda memiliki pesanan, maka Anda dapat menggunakan BST sebagai entri tabel hash untuk memegang objek dengan kode hash yang sama (collision). Namun, karena BST memiliki O (log 2 n) pencarian dan penyisipan, itu berarti kasus terburuk untuk seluruh struktur (tabel hash ditambah BST) secara teknis lebih baik daripada menggunakan daftar sebagai entri tabel. Tergantung pada implementasi BST, itu akan membutuhkan lebih banyak penyimpanan daripada daftar, tetapi kemungkinan tidak lebih.

Harap dicatat bahwa biasanya overhead dan perilaku BST tidak membawa apa-apa ke meja dalam situasi dunia nyata sebagai ember tabel hash, yang mengapa kinerja buruk daftar secara teoritis dapat diterima. Dengan kata lain, tabel hash mengkompensasi kelemahan daftar dengan menempatkan lebih sedikit item di setiap daftar (bucket). Namun : masalah secara khusus menyatakan bahwa tabel hash tidak dapat meningkat dalam ukuran, dan tabrakan lebih sering daripada khas dalam tabel hash.

Penerapan

Saya tidak akan meletakkan kode di sini karena jujur ​​itu tidak benar-benar diperlukan dan Anda tidak memberikan bahasa.

Apa yang akan saya lakukan adalah cukup menyalin tabel hash standar apa pun yang ada di perpustakaan standar bahasa Anda ke dalam kelas baru, lalu ubah tipe keranjang tabel dari daftar menjadi pohon. Bergantung pada bahasa dan pustaka standarnya, ini mungkin hal yang sangat sepele untuk dilakukan.

Biasanya saya tidak akan menganjurkan copy paste paste seperti ini. Namun, ini adalah cara mudah untuk mendapatkan struktur data yang teruji pertempuran dengan sangat cepat.


sumber
Dalam istilah asimptotik, menggunakan pohon biner untuk penanganan tabrakan tidak mengubah kinerja tabel hash yang diharapkan asalkan tabel hash sudah melakukan trik biasa untuk mencapai kinerja O (1) yang diamortisasi. Mengubah ukuran hashtable untuk memastikan kinerja yang baik berarti bahwa item yang diharapkan per ember (ukuran pohon biner) diharapkan juga kecil, sehingga Anda berakhir dengan O yang diamortisasi sama diharapkan (1) dengan cara apa pun. Bahkan untuk kasus terburuk - tanpa batasan penyeimbangan yang ditentukan, kinerja kasus terburuk untuk pohon biner adalah bahwa akhirnya berperilaku seperti daftar tertaut.
Steve314
@ Steve314 Perlu diingat bahwa masalahnya adalah ada banyak tabrakan, jadi dia mengharapkan ember berisi lebih banyak item daripada tabel hash biasanya.
Poin bagus - misalnya untuk tabel hash berukuran konstan dengan data tidak terikat, kinerja tabel hash asimptotik sama dengan kinerja asimptotik penanganan tumbukan - tabel hash hanya mengubah faktor konstan.
Steve314
@ Steve314 benar, pada dasarnya jika tabel hash tidak dapat secara efektif membatasi jumlah elemen dalam setiap ember, kinerja asimptotik menurun menjadi struktur sub-data apa pun yang digunakan dalam setiap ember. Saya menambahkan paragraf ke jawaban saya untuk memperjelas ini.
7

Menggunakan pohon biner untuk penanganan tabrakan di tabel hash tidak hanya mungkin - telah dilakukan.

Walter Bright paling dikenal sebagai penemu bahasa pemrograman D , tetapi juga menulis varian ECMAScript yang disebut DMDScript . Di masa lalu, klaim headline DMDScript (atau mungkin leluhur - saya sepertinya ingat nama DScript) adalah bahwa hashtable-nya cenderung mengungguli yang dalam banyak bahasa yang serupa. Alasannya - penanganan tabrakan menggunakan pohon biner.

Saya tidak ingat persis dari mana ini berasal, tetapi pohon-pohon yang digunakan adalah pohon biner naif, tanpa skema keseimbangan parsial (bukan AVL, merah-hitam atau apa pun) yang masuk akal karena menganggap hashtable itu sendiri akan diubah ukurannya ketika menjadi terlalu penuh dan Anda tidak mendapatkan tingkat tabrakan hash yang mustahil, pohon biner harus selalu kecil. Pada dasarnya, kasus terburuk masih sama dengan menggunakan daftar tertaut untuk penanganan tabrakan (kecuali Anda membayar harga dua pointer per node, bukan satu) tetapi kasus rata-rata mengurangi jumlah pencarian dalam setiap kotak hash.

Steve314
sumber