Mengapa algoritma rotasi pohon rentang memperhitungkan simpul induk dan kakek-nenek?

25

Saya tidak begitu mengerti mengapa rotasi dalam struktur data splay tree memperhitungkan tidak hanya induk dari simpul penilaian, tetapi juga kakek-nenek (operasi zig-zag dan zig-zig). Mengapa yang berikut ini tidak berfungsi:

Ketika kita memasukkan, misalnya, simpul baru ke pohon, kami memeriksa apakah kami memasukkan ke subtree kiri atau kanan. Jika kami menyisipkan ke kiri, kami memutar hasilnya KANAN, dan sebaliknya untuk subtree kanan. Secara rekursif akan menjadi seperti ini

Tree insert(Tree root, Key k){
    if(k < root.key){
        root.setLeft(insert(root.getLeft(), key);
        return rotateRight(root);
    }
    //vice versa for right subtree
}

Itu harus menghindari seluruh prosedur "pelebaran", bukan begitu?

Bober02
sumber

Jawaban:

30

Algoritma balancing yang lebih sederhana dapat membutuhkan waktu diamortisasi per rotasi dalam kasus terburuk. Misalkan pohon itu hanyalah jalan yang sama sekali tidak seimbang dari anak-anak yang benar; tidak ada simpul yang memiliki anak kiri. Satu-satunya daun di pohon ini adalah pohon dengan kunci maksimal. Jika Anda memutar langkah ini demi langkah ke root, Anda telah menggunakan rotasi , dan pohon yang dihasilkan masih sama sekali tidak seimbang.Ω(n)n-1

contoh buruk untuk hanya berputar

Sekarang misalkan kita berulang kali mempromosikan setiap node di pohon, satu per satu, dalam mengurangi urutan kunci, menggunakan algoritma yang lebih sederhana. Setelah semua promosi selesai, pohon telah kembali ke keadaan semula, dan kami telah menggunakan sekitar 2/2 rotasi. Dengan demikian, rata-rata, setiap promosi dalam urutan ini membutuhkan rotasi ; selain itu, saya dapat mengulangi pola ini selamanya. Jadi biaya perolehan diamortisasi untuk algoritma promosi ini adalah .n2/2Ω(n)Ω(n)

contoh buruk berlanjut

Contoh buruk ini muncul di kertas pohon splay asli Sleator dan Tarjan.

Algoritma splay mempertimbangkan tidak hanya satu node pada satu waktu, tetapi dua node pada suatu waktu. Khususnya, jika simpul yang direntangkan adalah anak yang tepat dari anak yang tepat, algoritma splay pertama-tama memutar induk , dan baru kemudian memutar .xxx

menyebarkan contoh yang buruk

Keuntungan dari algoritma yang lebih kompleks ini adalah bahwa ia tidak hanya membawa node yang diakses ke root, tetapi juga memindahkan setiap leluhur dari node yang diakses kira-kira setengah jalan ke root , tetapi tidak pernah memindahkan node apa pun lebih dari jumlah level yang konstan jauh dari akar.

Sleator dan Tarjan membuktikan bahwa waktu diamortisasi per splay hanya . (Buktinya menggunakan analisis kasus yang membosankan menggunakan fungsi potensial magis; jujur, jika Anda ingin tahu, cukup baca kertas asli.) Tentu saja satu rentang dapat mengambil waktu , tetapi mulai dengan pohon kosong, Anda harus melakukan banyak penyisipan dan splays untuk mengatur contoh yang buruk.HAI(logn)Ω(n)

Lebih singkat lagi: Splaying memindahkan node ke atas dengan cepat dan ke bawah dengan lambat.

JeffE
sumber
Saya pikir algoritma rotasi persis sama, saya hanya lebih pendek dan lebih mudah dimengerti. Daripada melihat kakek-nenek, saya hanya mempertimbangkan orangtua dalam satu langkah berputar. Bukankah itu menghasilkan hasil yang persis sama?
Bober02
Saya kira Anda mungkin merujuk pada dua algo SPLAYING, satu dari atas ke bawah, yang lain dari atas ke atas, dan bukan milik saya, apakah itu benar? Saya mengacu pada algo saya vs bottom up splaying
Bober02