Dua tumpukan dapat diimplementasikan secara efisien menggunakan satu larik berukuran tetap: tumpukan # 1 mulai dari ujung kiri dan tumbuh ke kanan, dan tumpukan # 2 mulai dari ujung kanan dan tumbuh ke kiri. Apakah sama mungkin untuk tiga tumpukan?
Lebih khusus lagi, apakah mungkin untuk mengimplementasikan tiga tumpukan dengan ketentuan sebagai berikut:
- Anda memiliki array ukuran tetap yang dapat menampung objek N.
- Selama jumlah dari tiga ukuran stack adalah <N, push () seharusnya tidak gagal.
- Operasi push () dan pop () harus menghabiskan waktu O (1).
- Selain array, Anda hanya dapat menggunakan O (1) ruang tambahan.
Berikut adalah contoh solusi yang tidak memenuhi persyaratan ini:
- Membagi array menjadi 3 bagian tetap dan menggunakan setiap bagian untuk tumpukan (melanggar 2).
- Mirip dengan di atas tetapi dengan batas bergerak di antara tumpukan (melanggar 3).
- Implementasi sederhana berdasarkan daftar tertaut (melanggar 4).
Saya akan menerima algoritma non-sepele atau bukti ketidakmungkinan bahkan jika mereka tidak memenuhi semua kondisi (1) - (4) persis, misalnya, sebuah algoritma di mana push / pop mengambil O (1) waktu diamortisasi, atau di mana memori tambahan lebih kecil dari O (N), misalnya O (log N). Atau bukti ketidakmungkinan yang menunjukkan bahwa misalnya, mengakses kurang dari 5 elemen array per push / pop tidak mungkin.
sumber
Jawaban:
Fredman dan Goldsmith menunjukkan dalam "Three Stacks" (Journal of Algorithms, 1994) bahwa sedikit ruang yang terbuang dapat dicapai. Ini juga minimum yang diperlukan untuk array ukuran setidaknya 16 quattuordecillion yottabytes. Saya menggambarkan algoritma sederhana yang membuang-buang kata ruang di jawaban StackOverflow saya untuk pertanyaan ini . Seperti @ dmitri-urbanowicz disebutkan dalam komentar, ini pada dasarnya hanya memperlakukan array sebagai blok ukuran , di mana setiap blok digunakan untuk tepat satu tumpukan dan berisi satu pointer ke blok berikutnya dalam tumpukan itu.Θ ( nε) Θ ( n--√) n--√ n--√
sumber
Misalkan N adalah panjang array yang mendasarinya. Saya bisa membayangkan tumpukan sebagai daftar tautan potongan besar, sehingga jumlah keseluruhan potongan tidak lebih dari O (log2 (N)). Tempatkan tumpukan ketiga di antara dua yang pertama, di indeks N / 2. Jadi kami memiliki 3 area yang ditempati dan 2 gratis. Ketika tumpukan tidak dapat menerima elemen berikutnya, ini berarti satu area bebas habis. Jika yang lain habis juga, maka seluruh memori habis. Jika tidak, ada area gratis lain dengan ukuran tidak lebih dari N / 2. Lanjutkan tumpukan yang meluap ke area bebas itu. sehingga seluruh konfigurasi menyerupai tata letak awal tumpukan. Karena memori bebas sekarang tidak lebih dari setengah dari inisial, tidak akan ada lebih dari log2 (N) dari operasi penautan tersebut. Setiap operasi penautan membutuhkan jumlah memori yang tetap untuk menyimpan status stack sebelumnya. Begitu,
sumber