Як реалізувати два стеки в одному масиві?


15

Хочу почати з того, що це НЕ є питанням домашнього завдання. Я читаю Вступ до алгоритмів - відомого тексту CLRS, щоб стати кращим програмістом. Я намагаюся самостійно вирішити проблеми та вправи, подані в книзі.

Я намагаюся вирішити вправу 10.1-2 з розділу 10 Елементарні структури даних з CLRS Second Edition. Ось що говориться про його:

Поясніть, як реалізувати два стеки в одному масиві A [1..n] таким чином, що жоден стек не переповнює, якщо загальна кількість елементів в обох стеках разом не дорівнює n . Операції PUSH та POP повинні виконуватись в O (1) час.

Досі я придумав таке рішення:

Нехай масив A [1..n] реалізує два стеки: S1 [1..i] і S2 [i..n] .

Для операцій PUSH-S1 та PUSH-S2 , якщо стек "повний", тоді починайте проштовхувати елементи в інший стек (наприклад, якщо стек S1 заповнений, коли новий елемент намагається ввести, тоді натисніть його на стек S2 і навпаки).

Проблема такого підходу полягає в тому, що я не зможу надійно POP-S1 або POP-S2, оскільки немає способу "запам'ятати", який елемент належить до якого стека. Якщо елементами стеку є пари (ключ, значення) , ключ - номер стека, то для виведення елемента, який я повинен був би шукати, в гіршому випадку, i або (ni) разів - який буде O (n ) (не соромтеся виправити мене, якщо я тут помиляюся), що не було б O (1) .

Я вже досить довго стукаю головою про це питання. Я на правильному шляху? Чи може хтось дати мої можливі вказівки для вирішення цієї проблеми?

Загалом, як я повинен «думати» про ці проблеми? Або лише справді розумні люди можуть вирішувати такі проблеми? Чи допоможе мені вирішити / вирішити подібні проблеми (тобто набути досвіду) мені стати кращим у цьому?

Я чекаю просвітлення.


3
"Чи допоможе мені вирішити / вирішити подібні проблеми (тобто набути досвіду) мені стати кращим у цьому?" На мій досвід, це безумовно так. Якщо нічого іншого, ви по-різному подумаєте про проблему, і тільки цим розвинете більше розуміння. Як мені недавно сказали: найкращий спосіб мати хороші ідеї - це мати багато ідей.
Г. Бах

Відповіді:


7

Ще один натяк на додаток до сказаного Ювалем: він допомагає розміщувати стеки певним чином у масивах та відповідно визначати їх напрямок зростання. Вони не повинні рости в одному напрямку.


5

Ось кілька підказок:

  1. Один з стеків повинен рости «вгору», а другий «вниз».
  2. Немає способу «запам’ятати», який елемент належить до якого стека - вам дозволяється використовувати додаткові змінні, щоб допомогти вам у подібних речах. (Це має більше сенсу при рішенні, запропонованому першою підказкою.)

1

Перший стек починається з 1 і виростає до n, тоді як другий починає форму n і зростає вниз до 1. Переповнення стека відбувається при натисканні елемента, коли два покажчики стека є сусідніми.


1

Цей метод ефективно використовує наявний простір. Це не викликає переповнення, якщо в arr [] є вільний простір. Ідея полягає у тому, щоб почати два стеки з двох крайніх кутів arr []. stack1 починається від самого лівого елемента, перший елемент в stack1 висувається з індексу 0. Стек2 починається з правого правого кута, перший елемент в stack2 висувається в індекс (n-1). Обидві стеки ростуть (або скорочуються) у зворотному напрямку. Щоб перевірити наявність переповнення, все, що нам потрібно перевірити, - це пробіл між верхніми елементами обох стеків.


-1

Я придумав інше рішення. Якщо ми розділимо масив навпіл (або як можна ближче, якщо масив має непарну довжину) і змусимо перший елемент перейти у перший стек, а другий перейти у другий стек. Під час вискакування ми могли вжити цих кроків. Однак, реалізуючи таким чином, це порушило б будь-який принцип стека?


Ласкаво просимо до інформатики ! На жаль, ваша пропозиція не працює. У масиві довжиниN, ви повинні мати можливість зберігати два стеки, які не переповнюватимуться, якщо їх загальний розмір не перевищить N (тому він повинен мати можливість справлятися з порожнім стеком і стеком довжиноюN). Ваше рішення переповнюється, якщо будь-який із стеків перевищуєN/2.
Девід Річербі

-2

Деякі натяки

Зробіть масив

Елементи масиву з непарним індексом призначені для stack1

Елементи масиву з рівним індексом призначені для stack2

Тепер ви можете вирощувати обидва стеки зліва направо

Просто зберігайте змінні, які підтримують верхнє положення обох стеків. Вам не доведеться шукати масив.

і якщо stack1 стає повним, поки stack2 порожній, ви можете відслідковувати додаткові елементи stack1 в stack2, підтримуючи деякі змінні


Це дуже суперечливо. Існуючі відповіді дають набагато простіші способи вирішення проблеми
Девід Річербі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.