Ada struktur data ini yang memperdagangkan kinerja akses array terhadap kebutuhan untuk mengulanginya saat membersihkannya. Anda menyimpan penghitung generasi dengan setiap entri, dan juga penghitung generasi global. Operasi "jelas" meningkatkan penghitung generasi. Pada setiap akses, Anda membandingkan penghitung generasi lokal vs global; jika berbeda, nilainya diperlakukan sebagai "bersih".
Ini muncul dalam jawaban di Stack Overflow baru-baru ini, tapi saya tidak ingat apakah trik ini memiliki nama resmi. Melakukannya?
Salah satu use case adalah algoritma Dijkstra jika hanya sebagian kecil dari node harus santai, dan jika ini harus dilakukan berulang kali.
algorithms
terminology
krlmlr
sumber
sumber
Jawaban:
Pendekatan yang disebutkan di atas mensyaratkan bahwa setiap sel dapat memiliki jumlah yang cukup besar untuk menampung berapa kali array mungkin perlu diinisialisasi ulang, yang merupakan penalti ruang yang substansial. Jika sebuah slot mampu memegang setidaknya satu nilai yang tidak akan pernah ditulis secara sah, seseorang dapat menghindari memiliki penalti ruang lain (tidak konstan) dengan mengorbankan menambahkan
O(Wlg(N))
penalti waktu, di manaW
jumlah slot array yang berbeda ditulis antara operasi kliring danN
ukuran array. Sebagai contoh, misalkan seseorang akan menyimpan bilangan bulat dari -2,147,483,647 ke 2,147,483,647 (tetapi tidak pernah -2,147,483,648) dan seseorang ingin item array kosong dibaca sebagai nol. Mulailah dengan mengisi array dengan -2,147.483.648 (sebut nilai ituB
). Saat membaca slot array untuk aplikasi, laporkan nilaiB
nol. Sebelum menulis Slot ArrayI
, periksa apakah itu diadakanB
dan jika demikian danI
lebih besar dari satu, menyimpan nol slotI/4
setelah melakukan pemeriksaan serupa untuk lokasi itu (dan, jika diadakanB
,I/16
, dll).Untuk menghapus array, mulailah dengan
I
sama dengan 0 atau 1, tergantung pada basis array (algoritma seperti yang dijelaskan akan bekerja untuk keduanya). Kemudian ulangi prosedur berikut: Jika itemI
adalahB
kenaikan,I
dan jika melakukannya menghasilkan kelipatan empat, bagi dengan empat (akhiri jika pembagian menghasilkan nilai 1); jika itemI
tidakB
, simpan diB
sana dan kalikanI
dengan empat (jikaI
dimulai dari nol, mengalikan dengan empat akan meninggalkannya nol, tetapi karena item 0 akan kosong,I
akan bertambah).Perhatikan bahwa seseorang dapat mengganti konstanta "empat" di atas dengan angka lain, dengan nilai yang lebih besar umumnya membutuhkan lebih sedikit penandaan kerja, tetapi nilai yang lebih kecil umumnya membutuhkan lebih sedikit pembersihan kerja; karena slot array yang ditandai harus dihapus, nilai tiga atau empat hampir pasti optimal; karena nilai empat pasti dekat dengan optimal, lebih baik dari dua atau delapan, dan lebih nyaman daripada angka lainnya, itu akan menjadi pilihan yang paling masuk akal.
sumber
Saya akan menyebutnya "lazy array sel reinitialization", tetapi tampaknya tidak memiliki nama mapan (yaitu, nama yang digunakan secara luas).
Algoritma ini cerdas, tetapi sangat terspesialisasi dan dapat diterapkan di area yang sangat sempit.
sumber
Saya percaya ini adalah kasus khusus memoisasi , kecuali dalam kasus ini, "memo" secara implisit "usia" dengan setiap kenaikan dari penghitung global. Saya kira semacam "memo mundur".
sumber