Implementasi struktur data immutable (persistent) seperti array dengan pengindeksan cepat, append, prepend, iterasi

11

Saya mencari struktur data persisten yang mirip dengan array (tetapi tidak bisa diubah), memungkinkan untuk pengindeksan cepat, menambahkan, prepend, dan operasi iterasi (good locality) operasi.

Clojure menyediakan vektor persisten, tetapi hanya untuk penambahan cepat. Scala's Vector secara efektif menambahkan dan menambah waktu, tetapi saya tidak dapat menerapkannya, karena ini didasarkan pada struktur data yang sama (bit-mapped vector trie) seperti vektor Clojure, dan, seperti yang saya mengerti, bit-mapped vector trie tidak dapat memiliki cepat cepat tanpa beberapa trik.

Saya tertarik bukan pada implementasi siap pakai tetapi pada deskripsi bagaimana mengimplementasikan struktur data sendiri.

Tvaroh
sumber

Jawaban:

13

Kandidat yang jelas adalah pohon biner seimbang yang persisten . Semua operasi yang Anda daftarkan dapat dilakukan dalam waktu atau O ( lg n ) , menggunakan penyalinan jalur . Untuk detail lebih lanjut tentang cara mencapai runtime ini, lihat buku Chris Okasaki yang dirujuk di bawah ini atau jawaban saya di sini .O(1)O(lgn)

Tentu saja, sebagai varian, setiap daun pohon seperti itu sendiri dapat berisi array yang tidak berubah (urutan nilai-nilai berurutan). Hal ini membuat memperbarui nilai menjadi kurang efisien, tetapi mungkin berhasil dengan baik untuk situasi Anda, jika Anda tidak pernah ingin mengubah nilai yang ada, cukup tambahkan dan tambahkan. Dengan cara ini, vektor Anda direpresentasikan sebagai urutan sekuens tidak berubah, direpresentasikan sebagai pohon biner seimbang dengan larik tidak berubah dalam daun. Ini memungkinkan pengindeksan cepat (logaritmik dalam jumlah daun), tambahkan cepat dan tambahkan, dan iterasi cepat. Kompleksitas asimptotik kasus terburuk tidak lebih baik, tetapi kinerja dalam praktik mungkin jauh lebih baik.

Referensi standarnya adalah buku Chris Okasaki tahun 1998 "Struktur data yang murni fungsional".
Lihat juga

DW
sumber
Terima kasih. Sepertinya pohon-RRB adalah kandidat yang baik, dan mereka sudah memiliki implementasi Clojure (tidak penuh).
Tvaroh
Saya kira Okasaki memberi tahu kami cara mencapai runtime ini di bawah ketetapan dan kegigihan?
Raphael
1
@ Raphael, yup. Saya telah menambahkan referensi untuk menjelaskan bagaimana Anda mencapai runtime (ke awal jawaban saya).
DW
4

Saya telah menggambarkan satu implementasi dari struktur data seperti itu dalam artikel saya tentang pencocokan ekspresi reguler tambahan - lihat http://jkff.info/articles/ire/#ropes-strings-with-fast-concatenation dan teks di bawah dan di atas bagian itu .

Beragam pohon dengan tinggi konstan (seperti pohon B atau 2-3 pohon). Pada dasarnya itu adalah pohon (2,3), yang daunnya (N, 2N-1) array, untuk menghindari overhead per-elemen. (A (N, 2N-1) array adalah array yang panjangnya di kisaran N..2N-1.) Lebih besar N memberi Anda overhead yang lebih kecil tetapi secara linear meningkatkan kompleksitas pemisahan dan penggabungan. Operasi seperti pengindeksan, pemisahan dan penggabungan sangat mirip dengan cara mereka bekerja di 2-3 pohon, generalisasi ke (N, 2N-1) di tingkat daun.

Jkff
sumber
Tautan putus; tolong berikan referensi yang tepat dan kuat (yang memungkinkan orang menemukan kertas Anda tanpa tautan).
Raphael
Saya tidak mempublikasikan koran di jurnal apa pun, hanya di situs web pribadi saya. Mungkin harus meletakkannya di Arxiv, ide bagus.
jkff
Saya sebagian besar memikirkan penulis, judul, dan tahun - yang membuat Googling lebih mudah jika perlu. Menaruhnya di arXiv akan lebih baik, benar!
Raphael