Anda dapat mempertahankan pohon AVL tanpa kunci atau sejenisnya.
Ini akan bekerja sebagai berikut: Pohon mempertahankan pemesanan pada node seperti halnya pohon AVL biasanya, tetapi alih-alih menentukan kunci di mana simpul "harus" terletak, tidak ada kunci, dan Anda harus secara eksplisit memasukkan node "setelah "node lain (atau dengan kata lain" di antara "dua node), di mana" setelah "berarti itu datang setelah itu dalam urutan traversal pohon. Dengan demikian pohon akan mempertahankan pemesanan untuk Anda secara alami, dan itu juga akan seimbang, karena AVL dibangun dalam rotasi. Ini akan menjaga semuanya terdistribusi secara otomatis.
Insersi
Selain penyisipan teratur ke dalam daftar, seperti yang ditunjukkan dalam pertanyaan, Anda akan mempertahankan pohon AVL yang terpisah. Penyisipan ke daftar itu sendiri adalahO ( 1 ), karena Anda memiliki simpul "sebelum" dan "setelah".
Waktu penyisipan ke pohon adalah O ( logn ), sama seperti penyisipan ke pohon AVL. Penyisipan melibatkan memiliki referensi ke simpul yang ingin Anda masukkan setelahnya, dan Anda cukup memasukkan simpul baru ke kiri simpul paling kiri dari anak kanan; lokasi ini "berikutnya" dalam urutan pohon (berikutnya dalam urutan melintang). Kemudian lakukan rotasi AVL khas untuk menyeimbangkan kembali pohon. Anda dapat melakukan operasi serupa untuk "masukkan sebelum"; ini berguna ketika Anda perlu memasukkan sesuatu ke awal daftar, dan tidak ada simpul "sebelum".
Menjawab pertanyaan
Untuk menjawab pertanyaan dari ( X<?Y), Anda cukup menemukan semua leluhur X dan Ydi pohon, dan Anda menganalisis lokasi di mana di pohon leluhur berbeda; yang menyimpang ke "kiri" adalah yang lebih rendah dari keduanya.
Prosedur ini memakan waktu O ( logn )waktu memanjat pohon ke akar dan mendapatkan daftar leluhur. Meskipun benar bahwa ini tampaknya lebih lambat daripada perbandingan bilangan bulat, kenyataannya adalah, itu sama; hanya perbandingan integer pada CPU yang dibatasi oleh konstanta besar untuk membuatnyaO ( 1 ); jika Anda melimpahi konstanta ini, Anda harus mempertahankan beberapa integer (O ( logn ) bilangan bulat sebenarnya) dan melakukan hal yang sama O ( logn )perbandingan. Sebagai alternatif, Anda dapat "mengikat" ketinggian pohon dengan jumlah konstan, dan "menipu" dengan cara yang sama dengan mesin dengan bilangan bulat: sekarang kueri akan tampakO ( 1 ).
Demonstrasi operasi penyisipan
Untuk menunjukkan, Anda dapat memasukkan beberapa elemen dengan urutannya dari daftar di pertanyaan:
Langkah 1
Dimulai dari D
Daftar:
Pohon:
Langkah 2
Memasukkan C, ∅ < C< D.
Daftar:
Pohon:
Catatan, Anda secara eksplisit dimasukkan C "sebelum" D, bukan karena huruf C sebelum D, tetapi karena C< D dalam daftar.
Langkah 3
Memasukkan SEBUAH, ∅ < A < C.
Daftar:
Pohon:
Rotasi AVL:
Langkah 4
Memasukkan B, A < B < C.
Daftar:
Pohon:
Tidak perlu rotasi.
Langkah 5
Memasukkan E, D < E< ∅
Daftar:
Pohon:
Langkah 6
Memasukkan F, B < F< C
Kami hanya meluruskannya "setelah" B di pohon, dalam hal ini hanya dengan melampirkannya Bbenar; jadiF sekarang tepat setelah B dalam traversal berurutan pohon.
Daftar:
Pohon:
Rotasi AVL:
Demonstrasi operasi perbandingan
SEBUAH<?F
ancestors(A) = [C,B]
ancestors(F) = [C,B]
last_common_ancestor = B
B.left = A
B.right = F
... A < F #left is less than right
D<?F
ancestors(D) = [C]
ancestors(F) = [C,B]
last_common_ancestor = C
C.left = D
C.right = B #next ancestor for F is to the right
... D < F #left is less than right
B<?SEBUAH
ancestors(B) = [C]
ancestors(A) = [B,C]
last_common_ancestor = B
B.left = A
... A < B #left is always less than parent
Sumber grafik