Реализовать стэк с помощью связного списка - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Необходимо на простом С реализовать структуру данных стэк с помошью связного списка. Так же реализовать работу с записью\выводом чисел из списка (IN\OUT) Но это в идеале. А вообще, буду очень благодарен, если просто объясните как на Си шке организовать стэк через двусторонний связный список.

Решение задачи: «Реализовать стэк с помощью связного списка»

textual
Листинг программы
#include "stack.h"
struct Stack
{
    struct item *top;
    DWORD count;
    HANDLE hHeap;
    CRITICAL_SECTION sec;
};
struct item
{
    PVOID data;
    struct item *next;
    DWORD tag;
    SIZE_T size;
};
BOOL CreateStack(struct Stack **stack)
{
    HANDLE hHeap;
    hHeap = HeapCreate(HEAP_NO_SERIALIZE, 0, 0);
    if (!hHeap)
    {
        return FALSE;
    }
    *stack = HeapAlloc(hHeap, 0, sizeof **stack);
    if (!*stack)
    {
        HeapDestroy(hHeap);
        return FALSE;
    }
    (*stack)->hHeap = hHeap;
    (*stack)->top = NULL;
    (*stack)->count = 0;
    InitializeCriticalSection(&(*stack)->sec);
    return TRUE;
}
BOOL StackPush(struct Stack **stack, PVOID data, SIZE_T size, DWORD tag)
{
    struct item *cr;
    EnterCriticalSection(&(*stack)->sec);
    cr = HeapAlloc((*stack)->hHeap, 0, sizeof *(*stack)->top);
    if (!cr)
    {
        LeaveCriticalSection(&(*stack)->sec);
        return FALSE;
    }
    cr->data = HeapAlloc((*stack)->hHeap, 0, size);
    if (!cr->data)
    {
        HeapFree((*stack)->hHeap, 0, cr);
        LeaveCriticalSection(&(*stack)->sec);
        return FALSE;
    }
    memmove(cr->data, data, size);
    cr->size = size;
    cr->tag = tag;
    cr->next = (*stack)->top;
    (*stack)->top = cr;
    (*stack)->count++;
    LeaveCriticalSection(&(*stack)->sec);
    return TRUE;
}
BOOL StackPop(struct Stack **stack, PVOID data, PSIZE_T size, PDWORD tag, void(*pfndel)(PVOID data, DWORD tag, SIZE_T size))
{
    struct item *cr;
    EnterCriticalSection(&(*stack)->sec);
    if (!(*stack)->top)
    {
        LeaveCriticalSection(&(*stack)->sec);
        return FALSE;
    }
    cr = (*stack)->top->next;
    memmove(data, (*stack)->top->data, (*stack)->top->size);
    if (size)
    {
        *size = (*stack)->top->size;
    }
    if (tag)
    {
        *tag = (*stack)->top->tag;
    }
    if (pfndel)
    {
        (*pfndel)((*stack)->top->data, (*stack)->top->tag, (*stack)->top->size);
    }
    HeapFree((*stack)->hHeap, 0, (*stack)->top->data);
    HeapFree((*stack)->hHeap, 0, (*stack)->top);
    (*stack)->top = cr;
    (*stack)->count--;
    LeaveCriticalSection(&(*stack)->sec);
    return TRUE;
}
VOID DestroyStack(struct Stack **stack)
{
    HANDLE hHeap;
    hHeap = (*stack)->hHeap;
    DeleteCriticalSection(&(*stack)->sec);
    HeapFree((*stack)->hHeap, 0, *stack);
    HeapDestroy(hHeap);
    *stack = NULL;
}
DWORD GetStackCountItem(struct Stack **stack)
{
    return (*stack)->count;
}

Объяснение кода листинга программы

  1. Структура stack содержит указатель на вершину стека, количество элементов в стеке, handle к куче и критическую секцию для синхронизации доступа к полю top.
  2. Структура item содержит указатель на следующий элемент в связном списке, указатель на данные, тег и размер данных.
  3. Функция CreateStack создает новый экземпляр стека. Сначала она выделяет память под структуру stack в куче, затем инициализирует поля структуры. Функция возвращает TRUE, если операция была успешна, и FALSE в противном случае.
  4. Функция StackPush добавляет новый элемент в стек. Она выделяет память под новый элемент в куче, копирует данные в новый элемент и добавляет новый элемент в связный список. Функция возвращает TRUE, если операция была успешна, и FALSE в противном случае.
  5. Функция StackPop удаляет верхний элемент из стека. Она копирует данные из верхнего элемента в указанный параметр data, затем удаляет элемент из стека. Функция возвращает TRUE, если операция была успешна, и FALSE в противном случае.
  6. Функция DestroyStack уничтожает экземпляр стека. Она освобождает память, выделенную под структуру stack, и уничтожает кучу.
  7. Функция GetStackCountItem возвращает текущее количество элементов в стеке.
  8. В связном списке каждый элемент содержит указатель на следующий элемент.
  9. Для синхронизации доступа к полю top используется критическая секция.
  10. В стек можно добавлять и удалять элементы только в конце и начале соответственно.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

9   голосов , оценка 3.778 из 5
Похожие ответы