Menemukan kasus tumpukan terburuk

8

Saya sedang mengerjakan masalah H dalam ACM ICPC 2004–2005 kontes Eropa Timur Laut .

Masalahnya pada dasarnya adalah untuk menemukan kasus terburuk yang menghasilkan jumlah maksimal dari pertukaran dalam algoritma (sift down) untuk membangun heap.

  • Input: File input berisi ( ).n1n50,000
  • Output: Output array yang berisi angka integer yang berbeda dari ke , sedemikian rupa sehingga merupakan heap, dan ketika mengonversinya menjadi array yang diurutkan, jumlah total pertukaran dalam operasi pengayakan maksimal mungkin.n1n

Input sampel: 6
Output yang sesuai:6 5 3 2 4 1

Dan dasar-dasar output:

[2, 1]   
[3, 2, 1]   
[4, 3, 1, 2] 
[5, 4, 3, 2, 1] 
[6, 5, 3, 4, 1, 2]
Jonaprieto
sumber
2
apakah Anda pada dasarnya bertanya "mengapa kode saya sangat lambat"? Saya pikir pertanyaan ini terlalu terlokalisasi, dan lagipula milik lebih baik di Stack Overflow
Ran G.
Tidak, sungguh, saya ingin mencari kasus terburuk untuk algoritma heapsort. Tetapi kode saya adalah upaya untuk memahami kasus-kasus ini.
jonaprieto
2
Jika Anda ingin mencoba heapsort pada semua kemungkinan susunan array, maka itu tidak terlalu mengejutkan algoritma Anda sangat lambat: itu akan memiliki waktu berjalan setidaknya Ω(n!), Yang tumbuh lebih dari eksponensial. 10! sudah 3,6 juta. Anda akan lebih baik dengan analisis teoretis. (mem-posting ulang komentar karena saya salah membaca awal pertanyaan Anda sehingga bagian kedua dari komentar saya tidak valid)
Alex ten Brink
Makalah ini tampaknya relevan. Aku berlari kedua; harap edit pertanyaan sehingga mengajukan pertanyaan tanpa boilerplate.
Raphael
Mungkin ini bermanfaat .

Jawaban:

4

Diberikan kasus terburuk untuk n, kita dapat membuat kasus terburuk untuk n+1 sebagai berikut: kami melakukan 'siklus swap' sebagai berikut: kami ambil n+1, masukkan a[0], dan kami bertukar a[0] dengan elemen maksimal anak-anaknya, yaitu a[1] atau a[2], yang kami tukar lagi dengan elemen maksimum anak-anaknya dan seterusnya, hingga kami meninggalkan ntumpukan elemen, pada titik mana kita meletakkan elemen terakhir di n+1posisi ke-5.

Contoh: kasus terburuk untuk n=5 adalah [5,4,3,2,1]. Kami bertukar dalam 6 yang menciptakan tumpukan[6,5,3,4,1], setelah itu kita berakhir dengan 2, yang kita masukkan di akhir: [6,5,3,4,1,2].

Metode di atas bekerja dengan induksi: kita mulai dari hasil terburuk untuk n1 elemen dan melakukan operasi sift-down secara terbalik, memaksimalkan jumlah swap yang harus dilakukan (log(n)swap). Anda tidak dapat melakukan lebih banyak swap daripada ini, jadi Anda memaksimalkan jumlah swap setelah operasi ekstrak-min pertama, setelah itu Anda dibiarkan dengan kasus terburuk untukn1elemen untuk operasi ekstrak-min berikutnya. Ini menyiratkan bahwa jumlah swap memang maksimal.

Perhatikan bahwa metode ini memberikan hasil yang berbeda dari yang Anda dapatkan:

[1]
[2, 1]
[3, 2, 1]
[4, 3, 1, 2]
[5, 4, 1, 3, 2]
[6, 5, 1, 4, 2, 3]
[7, 6, 1, 5, 2, 4, 3]
[8, 7, 1, 6, 2, 4, 3, 5]
[9, 8, 1, 7, 2, 4, 3, 6, 5]
[10, 9, 1, 8, 2, 4, 3, 7, 5 ,6]

Namun, kedua solusi itu benar:

[5, 4, 1, 3, 2]
[2, 4, 1, 3| 5]
[4, 2, 1, 3| 5]
[4, 3, 1, 2| 5]
[2, 3, 1| 4, 5]
[3, 2, 1| 4, 5]

[5, 4, 3, 2, 1]
[1, 4, 3, 2| 5]
[4, 1, 3, 2| 5]
[4, 2, 3, 1| 5]
[1, 2, 3| 4, 5]
[3, 2, 1| 4, 5]

[6, 5, 1, 4, 2, 3]
[3, 5, 1, 4, 2| 6]
[5, 3, 1, 4, 2| 6]
[5, 4, 1, 3, 2| 6]
[2, 4, 1, 3| 5, 6]
[4, 2, 1, 3| 5, 6]
[4, 3, 1, 2| 5, 6]
[2, 3, 1| 4, 5, 6]
[3, 2, 1| 4, 5, 6]

[6, 5, 3, 4, 1, 2]
[2, 5, 3, 4, 1| 6]
[5, 2, 3, 4, 1| 6]
[5, 4, 3, 2, 1| 6]
[1, 4, 3, 2| 5, 6]
[4, 1, 3, 2| 5, 6]
[4, 2, 3, 1| 5, 6]
[1, 2, 3| 4, 5, 6]
[3, 2, 1| 4, 5, 6]
Alex ten Brink
sumber
Tapi, contoh-contoh ini bukan tumpukan!
jonaprieto