Pembaruan: lihat di bawah untuk pembaruan tentang kesalahan operasi gabungan ini
Berikut ini adalah sketsa kasar dari solusi yang mungkin:
Saya pikir saya mungkin punya solusi untuk masalah ini menggunakan tipe B + -tree-seimbang acak. Seperti pohon treaps, pohon-pohon ini memiliki representasi yang unik. Tidak seperti treaps, mereka menyimpan beberapa kunci beberapa kali. Dimungkinkan untuk memperbaikinya dengan menggunakan trik dari Bent Trees et al "Biased Search Trees" untuk menyimpan setiap kunci hanya di level tertinggi (yaitu, paling dekat dengan root) di mana ia muncul)
Pohon untuk serangkaian nilai unik yang dibuat dibuat dengan pertama-tama mengaitkan setiap nilai dengan aliran bit, mirip dengan cara setiap nilai dalam treap dikaitkan dengan prioritas. Setiap node di pohon berisi kunci dan bit stream. Selain itu, simpul non-daun mengandung angka alami yang menunjukkan tinggi pohon yang berakar pada simpul itu. Node internal dapat memiliki jumlah anak yang tidak nol. Seperti B + -trees, setiap jalur yang tidak memotong sendiri dari akar ke daun memiliki panjang yang sama.
Setiap simpul internal berisi (seperti dalam B + -trees) kunci k terbesar dari daun turunannya. Masing-masing juga berisi bilangan alami i yang menunjukkan ketinggian pohon yang berakar pada v , dan aliran bit yang terkait dengan k dari bit i + 1 ke depan. Jika setiap kunci dalam pohon yang di-root pada v memiliki bit pertama yang sama dalam bit stream-nya, setiap anak v adalah daun dan i adalah 1 . Kalau tidak, anak-anak v adalah node internal yang semuanya memiliki bit ke- i yang sama dalam bit stream yang terkait dengan kunci mereka.vkivki+1vvi1vi
Untuk membuat pohon dari daftar kunci yang diurutkan dengan aliran bit terkait, pertama kumpulkan kunci menjadi kelompok yang berdekatan berdasarkan bit pertama di aliran mereka. Untuk masing-masing grup ini, buat induk dengan kunci dan bit stream dari kunci terbesar dalam grup, tetapi hilangkan bit pertama dari stream. Sekarang lakukan prosedur pengelompokan yang sama pada orang tua baru untuk membuat kakek-nenek. Lanjutkan sampai hanya satu simpul yang tersisa; ini adalah akar pohon.
Daftar kunci berikut dan (awal) bit stream diwakili oleh pohon di bawahnya. Di awalan bit stream, a '.' berarti sedikit pun. Artinya, setiap bit stream untuk kunci A dengan 0 di tempat pertama dengan menghasilkan pohon yang sama dengan yang lain, dengan asumsi tidak ada bit stream kunci lain yang berbeda.
A 0...
B 00..
C 10..
D 0...
E 0011
F 1...
G 110.
H 0001
____H____
/ \
E H
| / \
__E__ G H
/ | \ | |
B C E G H
/ \ | / \ / \ |
A B C D E F G H
Setiap anak dari simpul internal tertentu memiliki bit yang sama di tempat pertama dari bit stream-nya. Ini disebut "warna" dari induk - 0 berwarna merah, 1 berwarna hijau. Anak memiliki "rasa" tergantung pada bit pertama dari aliran bitnya - 0 adalah ceri, 1 adalah mint. Daun memiliki rasa, tetapi tidak berwarna. Menurut definisi, simpul ceri tidak dapat memiliki induk hijau, dan simpul mint tidak dapat memiliki induk merah.
n21−n (n−1i−1)(n+1)/2n≥2≤34nO(lgn)
Untuk bergabung dengan dua pohon dengan ketinggian yang sama, periksa terlebih dahulu untuk melihat apakah akarnya memiliki warna yang sama. Jika demikian, putuskan dari root kiri anak paling kanan dan dari root kanan anak paling kiri, kemudian secara rekursif bergabung dengan dua pohon ini. Hasilnya akan menjadi pohon dengan ketinggian yang sama atau lebih tinggi karena pohon memiliki rasa yang sama (lihat di bawah). Jika hasil rekursif bergabung dengan dua pohon memiliki ketinggian yang sama dengan dua anak yang putus, menjadikannya anak tengah dari akar dengan sisa anak-anak dari akar kiri sebelum dan sisa anak-anak dari akar kanan setelahnya. Jika lebih tinggi dari 1, jadikan anak-anak sebagai anak tengah dari akar dengan sisa anak dari akar kiri sebelum dan sisa anak-anak dari akar kanan setelahnya. Jika akar memiliki warna yang berbeda, periksa untuk melihat apakah mereka memiliki rasa yang sama. Jika mereka melakukannya, beri mereka induk baru dengan kunci dan bit stream dari root kanan, hilangkan bit pertamanya. Jika tidak, berikan masing-masing root induk baru dengan kunci dan bit stream dari root lama (eliding masing-masing bit pertama), kemudian secara rekursif bergabung dengan pohon-pohon itu.
1/21/2O(1)1/4, dan panggilan rekursif berikutnya selalu pada pohon dengan warna yang berbeda, sehingga analisis yang sama berlaku.
1/2O(1)
O(1)
a 01110
b 110..
c 10...
d 00000
Pohon yang dibuat dengan [a,b]
tinggi 2, pohon yang dibuat dengan [c,d]
tinggi 2, dan pohon yang dibuat dengan joinEqual (tree [a,b]) (tree [c,d])
tinggi 3. Namun, pohon yang dibuat [a,b,c,d]
memiliki tinggi 5.
Berikut adalah kode yang saya gunakan untuk menemukan kesalahan ini .