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 ( ).n1≤n≤50,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]

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 n−1 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 untukn−1elemen 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]

Tapi, contoh-contoh ini bukan tumpukan!
— jonaprieto
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.