Стек и структура данных

Я новичок в структуре данных и алгоритме, и я хочу спросить, почему необходимо реализовать стек с использованием массива через тип данных структуры, мы можем напрямую создавать глобальные функции pop и push, глобальный массив и верхнюю переменную, тогда почему мы создаем структуру и внутри этой структуры мы объявляем верхнюю переменную и указатель массива.

Я пытаюсь понять, каковы преимущества или недостатки метода реализации стека с использованием массива, в котором мы объявляем массив внутри структуры, а в другом мы напрямую создаем глобальный массив.

Можете ли вы предоставить код, показывающий два примера? Гораздо лучше увидеть код, чем описание кода.

Support Ukraine 21.08.2023 15:01

Если вы используете глобальный массив и глобальные функции, которые с ним работают, ваша программа может иметь только один стек.

Verpous 21.08.2023 15:03

@Verpous Если вам нужно N стеков в вашей программе, вы можете создать N массивов и N верхних переменных. Но по мере роста программы это может превратиться в беспорядок.

Support Ukraine 21.08.2023 15:12

ОТ: Стеки не обязательно реализовывать с использованием массивов...

Support Ukraine 21.08.2023 15:14

@SupportUkraine, конечно, но массив почти всегда является лучшим базовым представлением стека.

Cubic 21.08.2023 15:15

@Cubic Согласен. Но все же стоит знать, что это не закон природы.

Support Ukraine 21.08.2023 15:19

Мне не совсем понятно, о чем вы спрашиваете, но, скорее всего, основной ответ заключается в том, что то, что вы описываете, не является необходимым. Если вы хотите узнать о характеристиках конкретного подхода к реализации стека, лучше всего предоставить нам пример кода, о котором мы поговорим.

John Bollinger 21.08.2023 16:00

Все это сводится к следующему: «Почему бы не использовать глобальные переменные для всего, что нам нужно?» Это относится не только к стекам, но и к любой структуре данных. См. также Каковы плюсы и минусы использования глобальных переменных?

trincot 21.08.2023 16:50
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
8
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Полный ответ потребует долгого, долгого, долгого ответа. И это может превратиться в примеры, основанные на мнениях (что непопулярно/запрещено в SO. Но ниже я написал некоторые из многих вещей, которые вам следует учитывать впервые.

Вы смешиваете две несвязанные вещи. Использование структуры (struct) не мешает вам сделать стек глобальной переменной. Отсутствие структуры не мешает вам использовать локальный стек.

int stack_data[N];     // Global stack
int stack_size = 0;    // without a struct

struct stack {
    int data[N];
    int size;
};
struct stack stack = {0};   // Global stack using struct

void foo(void) {
    int foo_stack_data[N];     // Local stack
    int foo_stack_index = -1;  // without a struct
    ...
    ...
}

void bar(void) {
    struct stack bar_stack = {0};  // Local stack using struct
    ...
    ...
}

Есть несколько причин для использования struct. Сбор тесно связанных переменных, таких как «данные стека» и «размер стека», в struct во многих случаях облегчит чтение и поддержку вашего кода.

В качестве примера предположим, что вашей программе требуется 100 стеков. Без struct вам понадобится 2 * 100 = 200 строк кода. С struct stack вам понадобится всего 100 строк (плюс 4 для определения). И ситуация будет только ухудшаться по мере увеличения количества переменных, связанных со структурой данных.

И если вам нужен динамически выделенный стек, один вызов malloc будет работать с использованием struct, тогда как вам понадобятся 2 вызова malloc без struct.

Глобальные переменные.... хммм, бывают ситуации, когда (несколько) глобальных переменных имеют смысл. Но широкое использование глобальных переменных (почти) всегда приводит к путанице. Хорошее правило — избегать глобальных переменных, если у вас нет очень веских аргументов.

Посмотри на это:

int stack_data[N];     // Global stack
int stack_size = 0;    // without a struct

void push(int value) {
    // error check omitted
    stack_data[stack_size] = value;
    stack_size = stack_size + 1;
}

void bar(void) {
    push(42);
}

Что ж... это сработает. Но... что, если мне нужно две стопки или 8 стопок? Должен ли я тогда написать 8-ю версию функции push? Мне это не кажется забавным...

Итак, я делаю:

void push(int value, int* d, int* sz) {
    // error check omitted
    d[*sz] = value;
    *sz = *sz + 1;
}

void bar(void) {
    push(42, stack_data, &stack_size);
    push(65, another_stack_data, &another_stack_size);
}

Передача переменной, связанной со стеком, позволяет мне иметь несколько стеков.

Но мне пришлось передать и данные, и размер. Два аргумента. А что, если мне нужно 5 переменных для описания моей структуры данных... тогда мне придется передать 5 аргументов. Помимо всего набора текста, это также могло бы ухудшить производительность.

Используя метод struct, я мог бы использовать один аргумент, то есть указатель на переменную struct:

void push(int value, struct stack *s) {
    // error check omitted
    s->data[s->size] = value;
    s->size = s->size + 1;
}

void bar(void) {
    struct stack stack1 = {0};
    push(42, &stack1);
    struct stack stack2 = {0};
    push(65, &stack2);
    ...
}

Другие вопросы по теме