Яка різниця між масивом і стеком?


10

За даними Вікіпедії, стек :

є абстрактним типом даних та лінійною структурою даних останнім, першим (LIFO).

Під час масиву :

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

Наскільки я розумію, вони досить схожі. Отже, які основні відмінності? Якщо вони не однакові, що може зробити масив, що стек не може, і навпаки?


5
Як ваше запитання не відповідає тим, що ви знайшли у Вікіпедії? Ви можете отримати доступ до елементів масиву в будь-якому порядку; доступ до стека має бути в порядку LIFO.
Калеб

8
@Caleb Це те, що ти щось читаєш, не означає, що ти розумієш концепцію. На моїй думці я не цілком зрозумів це, поки не запитав.
Динамічний

3
-1 Ви в основному опублікували відповідь у власному запитанні. Що ти знову запитуєш?
Андрес Ф.

1
@AndresF. Я не можу зрозуміти, що це означає ... Якби ти подивився статтю у Вікіпедії та зрозумів, що вони говорять вперше, світ був би ідеальним.
Динамічний

2
Я щойно прочитав мета.програмери і зрозумів, чому ви задали це не питання: це для конкурсу. Я серйозно сумніваюся, що ви не зрозуміли статтю у Вікіпедії. Ганьба вам: /
Андрес Ф.

Відповіді:


45

Ну, ви, звичайно, можете реалізувати стек з масивом. Різниця полягає в доступі. У масиві у вас є список елементів, і ви можете отримати доступ до будь-якого з них у будь-який час. (Придумайте купу дерев’яних блоків, всі викладені підряд.)

Але в стеку немає жодної операції з випадковим доступом; Є тільки Push, Peekі Popвсі вони мають справу виключно з елементом у верхній частині стека. (Подумайте про дерев'яні блоки, складені вертикально зараз. До верху башти нічого не можна торкатися, інакше воно перевалиться.)


11
дерев'яні блоки - приємна аналогія
Джессі Блек

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

стеки, безумовно, реалізовані з випадковим доступом
old_timer

4
Ви повинні смоктати Дженгу.
НевдоволенийГот

1
@ Мейсон, я знаю. Це був жарт.
НевдоволенийГот

6

У чистому стеку, тільки допустимі операції Push, Popі , Peekале з практичної точки зору, це не зовсім вірно. А точніше, Peekоперація часто дозволяє дивитись в будь-якій позиції стека, але привід полягає в тому, що це відносно одного кінця стека.

Отже, як уже говорили інші, масив є випадковим доступом і все посилається на початок масиву .

У стеці ви можете додавати / видаляти лише на робочому кінці стеку, але у вас все ще є випадковий доступ до читання, але він посилається на робочий кінець . У цьому принципова різниця.

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

Це одне конкретне використання / реалізація, але це ілюструє різницю: на масив завжди посилається з початку, але на стеки завжди посилається з деякого робочого кінцевого положення.

Однією з можливих реалізацій стека є масив плюс індекс, щоб запам'ятати, де знаходиться робочий кінець.


Для мене це відповідь. Питання в чому різниця між масивом і стеком зводиться до того, для чого нам потрібен стек, коли масив здається менш обмеженим і більш універсальним. І це відповідає на це: саме тому, що стек обмежений тим, що використання його у відповідних випадках (наприклад, виклики функцій тут) робить реалізацію логічною. Хенко "красуня"
Тоданлі

4

Я думаю, що найбільша плутанина, що відбувається тут, - це реалізація порівняно з базовими структурами даних.

У більшості (більш основних мов) масив являє собою набір елементів з фіксованою довжиною, до яких можна отримати доступ будь-який в даний момент часу. Той факт, що у вас є маса таких елементів, нічого не говорить про те, як його використовувати (і, чесно кажучи, комп'ютер не буде знати / дбати, як ви ним користуєтесь, доки ви не порушите використання).

Стек - це абстракція, яка використовується для представлення даних, з якими слід обробляти певним чином. Це абстрактне поняття, оскільки воно просто говорить про те, що воно повинно мати деяку підпрограму / метод / функцію, яка може додавати вгорі або видаляти зверху, в той час як дані, розташовані нижче, не торкаються. Зрозуміло, ваш вибір використовувати масив таким чином.

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

Таким чином, ви можете використовувати масив для складання стека, але вони не еквівалентні


3

Їх обов'язки різні:

  • Стек повинен бути в змозі виводити елементи на стек і виштовхувати елементи зі стека, отже, чому він зазвичай має методи Pop()таPush()

  • Відповідальність масиву полягає в тому, щоб отримати / встановити елемент у визначеному індексі


3

Ви можете отримати елемент з будь-якого індексу масиву A \.

За допомогою стека ви можете отримати елемент посередині стека A, використовуючи інший стек: B.

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

Отже, для даних, для яких потрібна можливість отримання довільного індексу, з стеком важче працювати.

У ситуації, коли ви хочете поведінку "останнє, перше", стек дасть вам менше витрат, ніж масив.


0

Я б не пішов так далеко, щоб сказати, що вони "дуже схожі".

Масив використовується для зберігання речей, до яких згодом буде доступний послідовно або через індекс. Структура даних не передбачає будь-якого способу доступу (FIFO, LIFO, FILO тощо), але вона може бути використана таким чином, якщо ви хочете.

Стек - це спосіб відстеження речей під час їх створення. Метод доступу мається на увазі / потрібен залежно від типу створеного стека. Фреймний стек буде прикладом LIFO. Відмова від відповідальності - я, можливо, змішую свою таксономію структури даних, і стек може по-справжньому дозволити лише LIFO. Інакше це буде інший тип черги.

Тому я міг би використовувати масив як стек (хоча я цього не хотів), але я не можу використовувати стек як масив (якщо я над цим не працюю дуже важко).


1
У сфері "структур для зберігання колекцій об'єктів" я б не сказав, що вони дуже схожі. Що стосується концепцій програмування, я б сказав, що вони досить схожі. Як правило, в області речей я б сказав, що вони майже однакові.
Кірк Бродхерст

0

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


0

Масив з точки зору програмістів, закріплений за місцем і розміром, ви знаєте, де ви знаходитесь в ньому і де вся справа. Ви маєте доступ до всього цього.

Зі штабелем ви сидите на одному кінці його, але не маєте уявлення про його розмір і про те, як далеко ви можете спокійно зайти. Ваш доступ до нього обмежений сумою, яку ви виділили, ви часто навіть не знаєте, чи виділяєте потрібну суму, якщо ви просто засунули в кучу чи програму. Ваш погляд на стек - це невеликий масив, який ви самі виділили, розмір, який ви хотіли, ви маєте контроль над і можете бачити. Ваша частина не відрізняється від масиву. Різниця полягає в тому, що ваш масив прикріплений до кінця іншого масиву заради аргументів та термінології, які ви не маєте видимості, не маєте ідеї, наскільки великий чи малий, і ви не можете доторкнутися до нього, не завдаючи шкоди. Масив, якщо не глобальний, часто все-таки реалізується на стеку, тому масив та стек ділять однаковим простором протягом тривалості цієї функції.

Якщо ви хочете потрапити на апаратну сторону, то, звичайно, це процесор, але звичайно масив заснований на відомій початковій точці / адресі, розмір відомий компілятором / програмістом, а адреси обчислюються в ньому, іноді використовуючи адресацію зміщення регістру (завантажуйте значення з адреси, визначеної цим базовим регістровим значенням, плюс це значення регістру зміщення; аналогічно при компіляції це може бути негайне зміщення, не обов'язково засноване на реєстрації, залежить від процесора, звичайно), яке в зборі дуже нагадує доступ до масиву в коді високого рівня. Точно так само і з стеком, якщо він є, ви можете використовувати реєстрацію або негайну зміщення адреси, часто, хоча для цього використовується спеціальний реєстр, або сам покажчик стека, або реєстр, зарезервований компілятором / програмістом, який буде використовуватися для доступу до кадру стека для цього функція. А для деяких процесорів використовуються спеціальні функції доступу до стеку та / або потрібні для доступу до стеку. У вас є інструкції push і pop, але вони використовуються не так часто, як ви могли б подумати, і справді не застосовуєтесь до цього питання. Для деяких процесорів push і pop - псевдоніми для інструкцій, які можна використовувати з будь-яким регістром у будь-якому місці, а не лише вказівником стека на стеку, що надалі усуває зв'язок push та pop з цим питанням.

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