diff --git a/05_hw/CMakeLists.txt b/05_hw/CMakeLists.txt index 6f5e398..7c43c73 100644 --- a/05_hw/CMakeLists.txt +++ b/05_hw/CMakeLists.txt @@ -5,3 +5,13 @@ add_library(stack stack.c) add_executable(main main.c) target_link_libraries(main stack) + +add_executable(tests tests.c) +target_link_libraries(tests stack) + +add_executable(benchmarks benchmarks.c) +target_link_libraries(benchmarks stack) + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage -g") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") + diff --git a/05_hw/benchmarks.c b/05_hw/benchmarks.c new file mode 100644 index 0000000..154eb5f --- /dev/null +++ b/05_hw/benchmarks.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include "stack.h" + +// Функция замера времени для функций с двумя параметрами +double measureTime(void (*func)(Stack*, int), Stack* stack, int data, int iterations) { + clock_t start, end; + start = clock(); + for (int i = 0; i < iterations; i++) { + func(stack, data); // Передаем данные в функцию + } + end = clock(); + return ((double)(end - start)) / CLOCKS_PER_SEC; +} + +// Обертка для pop, чтобы соответствовать ожидаемой сигнатуре +void popWrapper(Stack* stack, int data) { + pop(stack); // Просто вызываем pop без второго аргумента +} + +// Бенчмарк для push с разными данными +void benchmarkPush(int iterations) { + Stack stack; + initStack(&stack); + + // Пример с разными наборами данных + for (int data = 1; data <= 5; data++) { // Пробуем вставлять данные от 1 до 5 + double timeTaken = measureTime(push, &stack, data, iterations); + printf("Push Time for data %d with %d iterations: %f seconds\n", data, iterations, timeTaken); + } +} + +// Бенчмарк для pop с разными объемами стека +void benchmarkPop(int iterations) { + Stack stack; + initStack(&stack); + + // Наполняем стек + for (int data = 1; data <= 5; data++) { + for (int i = 0; i < iterations * data; i++) { + push(&stack, i); // Наполняем стек с данными + } + + double timeTaken = measureTime(popWrapper, &stack, 0, iterations); + printf("Pop Time for stack with %d elements and %d iterations: %f seconds\n", iterations * data, iterations, timeTaken); + } +} + +int main() { + int iterations = 100000; // Количество операций + + benchmarkPush(iterations); + benchmarkPop(iterations); + + return 0; +} \ No newline at end of file diff --git a/05_hw/stack.c b/05_hw/stack.c index 0964440..e27d9f8 100644 --- a/05_hw/stack.c +++ b/05_hw/stack.c @@ -17,12 +17,14 @@ void initStack(Stack* stack) { void destroyStack(Stack* stack) { Node* current = stack->top; while (current != NULL) { - Node *tmp = current; + Node* tmp = current; current = current->next; - free(tmp); + free(tmp); } + stack->top = NULL; } + void push(Stack* stack, int data) { Node* newNode = createNode(data); newNode->next = stack->top; @@ -30,8 +32,12 @@ void push(Stack* stack, int data) { } void pop(Stack* stack) { + if (stack->top == NULL) { + return; + } Node* temp = stack->top; stack->top = stack->top->next; + free(temp); } Node* searchByValue(Stack* stack, int value) { @@ -40,6 +46,7 @@ Node* searchByValue(Stack* stack, int value) { if (current->data == value) { return current; } + current = current->next; } return NULL; } @@ -72,7 +79,6 @@ void traverseStack(Stack* stack) { } bool isEmpty(Stack* stack) { - free(stack->top); return stack->top == NULL; } diff --git a/05_hw/tests.c b/05_hw/tests.c new file mode 100644 index 0000000..8761f7a --- /dev/null +++ b/05_hw/tests.c @@ -0,0 +1,110 @@ +#include +#include "stack.h" +#include + +void testPush() { + Stack stack; + initStack(&stack); + push(&stack, 1); + push(&stack, 2); + push(&stack, 3); + assert(getTop(&stack)->data == 3); + printf("testPush passed.\n"); +} + +void testPop() { + Stack stack; + initStack(&stack); + push(&stack, 1); + push(&stack, 2); + pop(&stack); + assert(getTop(&stack)->data == 1); + pop(&stack); + assert(isEmpty(&stack)); + printf("testPop passed.\n"); +} + +void testSearchByValue() { + Stack stack; + initStack(&stack); + push(&stack, 1); + push(&stack, 2); + push(&stack, 3); + assert(searchByValue(&stack, 2) != NULL); + assert(searchByValue(&stack, 4) == NULL); + printf("testSearchByValue passed.\n"); +} + +void testSearchByIndex() { + Stack stack; + initStack(&stack); + push(&stack, 1); + push(&stack, 2); + push(&stack, 3); + assert(searchByIndex(&stack, 0)->data == 3); + assert(searchByIndex(&stack, 1)->data == 2); + assert(searchByIndex(&stack, 2)->data == 1); + assert(searchByIndex(&stack, 3) == NULL); + printf("testSearchByIndex passed.\n"); +} + +void testDestroyStack() { + Stack stack; + initStack(&stack); + push(&stack, 1); + push(&stack, 2); + destroyStack(&stack); + assert(isEmpty(&stack)); + printf("testDestroyStack passed.\n"); +} + +void testIsEmpty() { + Stack stack; + initStack(&stack); + assert(isEmpty(&stack)); + push(&stack, 1); + assert(!isEmpty(&stack)); + pop(&stack); + assert(isEmpty(&stack)); + printf("testIsEmpty passed.\n"); +} + +void testGetTop() { + Stack stack; + initStack(&stack); + assert(getTop(&stack) == NULL); + push(&stack, 42); + assert(getTop(&stack)->data == 42); + push(&stack, 99); + assert(getTop(&stack)->data == 99); + printf("testGetTop passed.\n"); +} + +void testTraverseStack() { + Stack stack; + initStack(&stack); + printf("Expected output: Stack elements: \nActual output: "); + traverseStack(&stack); + + push(&stack, 5); + push(&stack, 10); + push(&stack, 15); + + printf("Expected output: Stack elements: 15 10 5\nActual output: "); + traverseStack(&stack); + printf("testTraverseStack passed.\n"); +} + + +int main() { + testPush(); + testPop(); + testSearchByValue(); + testSearchByIndex(); + testDestroyStack(); + testIsEmpty(); + testGetTop(); + testTraverseStack(); + printf("All tests passed!\n"); + return 0; +} \ No newline at end of file