From c15c5e36bd104ee75e15ac2f240d280ed1c35dcd Mon Sep 17 00:00:00 2001 From: mrskristinaa Date: Wed, 15 Oct 2025 12:00:46 +0300 Subject: [PATCH 01/23] added definition of class Queue --- CMakeLists.txt | 1 + lib_queue/CMakeLists.txt | 1 + lib_queue/queue.cpp | 0 lib_queue/queue.h | 0 4 files changed, 2 insertions(+) create mode 100644 lib_queue/CMakeLists.txt create mode 100644 lib_queue/queue.cpp create mode 100644 lib_queue/queue.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ed05fc1..f4e4319e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ include(cmake/function.cmake) # подхватываем функции, # и для создания исполняемого проекта в отдельные функции add_subdirectory(lib_easy_example) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example +add_subdirectory(lib_queue) add_subdirectory(main) # подключаем дополнительный CMakeLists.txt из подкаталога с именем main option(BTEST "build test?" ON) # указываем подключаем ли google-тесты (ON или YES) или нет (OFF или NO) diff --git a/lib_queue/CMakeLists.txt b/lib_queue/CMakeLists.txt new file mode 100644 index 00000000..f0846b24 --- /dev/null +++ b/lib_queue/CMakeLists.txt @@ -0,0 +1 @@ +create_project_lib(Queue) \ No newline at end of file diff --git a/lib_queue/queue.cpp b/lib_queue/queue.cpp new file mode 100644 index 00000000..e69de29b diff --git a/lib_queue/queue.h b/lib_queue/queue.h new file mode 100644 index 00000000..e69de29b From 1b3f941c7fe6a7de5ce536b00357b1cbc6472b01 Mon Sep 17 00:00:00 2001 From: mrskristinaa Date: Wed, 22 Oct 2025 01:16:31 +0300 Subject: [PATCH 02/23] added definition of class Queue --- lib_queue/queue.h | 90 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/lib_queue/queue.h b/lib_queue/queue.h index e69de29b..34d7137e 100644 --- a/lib_queue/queue.h +++ b/lib_queue/queue.h @@ -0,0 +1,90 @@ +#pragma once +#ifndef QUEUE_H +#define QUEUE_H +#include + +template +class Queue { +private: + T* _data; + int _size; + int _head; + int _count; + +public: + explicit Queue(int size = 100); + ~Queue(); + + void enqueue(const T& val); + void dequeue(); + inline T front() const; + inline bool is_empty() const noexcept; + inline bool is_full() const noexcept; + inline int size() const noexcept; + void clear() noexcept; +}; + +template +Queue::Queue(int size) : _size(size), _head(0), _count(0) { + if (size <= 0) { + throw std::invalid_argument("Queue size must be positive"); + } + _data = new T[_size]; +} + +template +Queue::~Queue() { + delete[] _data; +} + +template +void Queue::enqueue(const T& val) { + if (is_full()) { + throw std::logic_error("Queue is full"); + } + + int tail = (_head + _count) % _size; + _data[tail] = val; + _count++; +} + +template +void Queue::dequeue() { + if (is_empty()) { + throw std::logic_error("Queue is empty"); + } + + _head = (_head + 1) % _size; + _count--; +} + +template +T Queue::front() const { + if (is_empty()) { + throw std::logic_error("Queue is empty"); + } + return _data[_head]; +} + +template +bool Queue::is_empty() const noexcept { + return _count == 0; +} + +template +bool Queue::is_full() const noexcept { + return _count == _size; +} + +template +int Queue::size() const noexcept { + return _count; +} + +template +void Queue::clear() noexcept { + _head = 0; + _count = 0; +} + +#endif // QUEUE_H \ No newline at end of file From 826ce3f37123ed19b924bb2c35d1dfa0ec54b2fa Mon Sep 17 00:00:00 2001 From: mrskristinaa Date: Wed, 22 Oct 2025 01:45:15 +0300 Subject: [PATCH 03/23] added definition of class Queue --- lib_queue/queue.h | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/lib_queue/queue.h b/lib_queue/queue.h index 34d7137e..8324a5a9 100644 --- a/lib_queue/queue.h +++ b/lib_queue/queue.h @@ -10,14 +10,15 @@ class Queue { int _size; int _head; int _count; - public: explicit Queue(int size = 100); + Queue(const Queue& other); + Queue& operator=(const Queue& other); ~Queue(); - void enqueue(const T& val); void dequeue(); inline T front() const; + inline T back() const; inline bool is_empty() const noexcept; inline bool is_full() const noexcept; inline int size() const noexcept; @@ -32,6 +33,33 @@ Queue::Queue(int size) : _size(size), _head(0), _count(0) { _data = new T[_size]; } +template +Queue::Queue(const Queue& other) : _size(other._size), _head(other._head), _count(other._count) { + _data = new T[_size]; + for (int i = 0; i < _count; i++) { + int index = (other._head + i) % other._size; + _data[index] = other._data[index]; + } +} + +template +Queue& Queue::operator=(const Queue& other) { + if (this != &other) { + delete[] _data; + + _size = other._size; + _head = other._head; + _count = other._count; + + _data = new T[_size]; + for (int i = 0; i < _count; i++) { + int index = (other._head + i) % other._size; + _data[index] = other._data[index]; + } + } + return *this; +} + template Queue::~Queue() { delete[] _data; @@ -42,7 +70,6 @@ void Queue::enqueue(const T& val) { if (is_full()) { throw std::logic_error("Queue is full"); } - int tail = (_head + _count) % _size; _data[tail] = val; _count++; @@ -53,7 +80,6 @@ void Queue::dequeue() { if (is_empty()) { throw std::logic_error("Queue is empty"); } - _head = (_head + 1) % _size; _count--; } @@ -66,6 +92,15 @@ T Queue::front() const { return _data[_head]; } +template +T Queue::back() const { + if (is_empty()) { + throw std::logic_error("Queue is empty"); + } + int tail = (_head + _count - 1) % _size; + return _data[tail]; +} + template bool Queue::is_empty() const noexcept { return _count == 0; From 4f132dae1376d2027afdf3d272baf548f0ed57a2 Mon Sep 17 00:00:00 2001 From: mrskristinaa Date: Wed, 22 Oct 2025 03:01:27 +0300 Subject: [PATCH 04/23] added definition of class Stack --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ed05fc1..7ba0d8a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,8 @@ include(cmake/function.cmake) # подхватываем функции, # для простоты мы объединили наборы команд для создания статической библиотеки # и для создания исполняемого проекта в отдельные функции -add_subdirectory(lib_easy_example) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example +add_subdirectory(lib_easy_example) +add_subdirectory(build/lib_stack) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example add_subdirectory(main) # подключаем дополнительный CMakeLists.txt из подкаталога с именем main option(BTEST "build test?" ON) # указываем подключаем ли google-тесты (ON или YES) или нет (OFF или NO) From b610809e5e1b415d990caac6bd744438e3cceb21 Mon Sep 17 00:00:00 2001 From: mrskristinaa Date: Wed, 22 Oct 2025 12:23:53 +0300 Subject: [PATCH 05/23] added definition of class Algorithms --- CMakeLists.txt | 6 +- lib_algorithms/CMakeLists.txt | 2 + lib_algorithms/algorithms.cpp | 21 ++++++ lib_algorithms/algorithms.h | 5 ++ lib_stack/CMakeLists.txt | 1 + lib_stack/stack.cpp | 0 lib_stack/stack.h | 76 ++++++++++++++++++++ tests/test_algorithms.cpp | 35 +++++++++ tests/test_stack.cpp | 132 ++++++++++++++++++++++++++++++++++ 9 files changed, 276 insertions(+), 2 deletions(-) create mode 100644 lib_algorithms/CMakeLists.txt create mode 100644 lib_algorithms/algorithms.cpp create mode 100644 lib_algorithms/algorithms.h create mode 100644 lib_stack/CMakeLists.txt create mode 100644 lib_stack/stack.cpp create mode 100644 lib_stack/stack.h create mode 100644 tests/test_algorithms.cpp create mode 100644 tests/test_stack.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ba0d8a2..634062df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,8 +13,10 @@ include(cmake/function.cmake) # подхватываем функции, # для простоты мы объединили наборы команд для создания статической библиотеки # и для создания исполняемого проекта в отдельные функции -add_subdirectory(lib_easy_example) -add_subdirectory(build/lib_stack) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example +add_subdirectory(lib_easy_example) +#add_subdirectory(lib_queue) +add_subdirectory(lib_stack) +add_subdirectory(lib_algorithms) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example add_subdirectory(main) # подключаем дополнительный CMakeLists.txt из подкаталога с именем main option(BTEST "build test?" ON) # указываем подключаем ли google-тесты (ON или YES) или нет (OFF или NO) diff --git a/lib_algorithms/CMakeLists.txt b/lib_algorithms/CMakeLists.txt new file mode 100644 index 00000000..cbdb9b66 --- /dev/null +++ b/lib_algorithms/CMakeLists.txt @@ -0,0 +1,2 @@ +create_project_lib(Algorithms) +add_depend(Algorithms Stack ..\\lib_stack) diff --git a/lib_algorithms/algorithms.cpp b/lib_algorithms/algorithms.cpp new file mode 100644 index 00000000..e41593a9 --- /dev/null +++ b/lib_algorithms/algorithms.cpp @@ -0,0 +1,21 @@ +#include "algorithms.h" +#include "stack.h" +bool check_algorithms(const std::string& symbol) { + Stack stack; + for (char ch : symbol) { + if (ch == '(' || ch == '{' || ch == '[') { + stack.push(ch); + } + else if (ch == ')' || ch == '}' || ch == ']') { + if (stack.is_empty()) { + return false; + } + char top_char = stack.top(); + stack.pop(); + if ((ch == ')' && top_char != '(') || (ch == '}' && top_char != '{') || (ch == ']' && top_char != '[')) { + return false; + } + } + } + return stack.is_empty(); +} \ No newline at end of file diff --git a/lib_algorithms/algorithms.h b/lib_algorithms/algorithms.h new file mode 100644 index 00000000..0003135c --- /dev/null +++ b/lib_algorithms/algorithms.h @@ -0,0 +1,5 @@ +#ifndef ALGORITHMS_H +#define ALGORITHMS_H +#include +bool check_algorithms(const std::string& symbol); +#endif // ALGORITHMS_H \ No newline at end of file diff --git a/lib_stack/CMakeLists.txt b/lib_stack/CMakeLists.txt new file mode 100644 index 00000000..77959ec8 --- /dev/null +++ b/lib_stack/CMakeLists.txt @@ -0,0 +1 @@ +create_project_lib(Stack) diff --git a/lib_stack/stack.cpp b/lib_stack/stack.cpp new file mode 100644 index 00000000..e69de29b diff --git a/lib_stack/stack.h b/lib_stack/stack.h new file mode 100644 index 00000000..d346b59f --- /dev/null +++ b/lib_stack/stack.h @@ -0,0 +1,76 @@ +#pragma once +#ifndef STACK_H +#define STACK_H +#include +template +class Stack { +private: + T* _data; + int _size; + int _top; + +public: + explicit Stack(int size = 100); + ~Stack(); + + void push(const T& val); + void pop(); + inline T top() const; + inline bool is_empty() const noexcept; + inline bool is_full() const noexcept; + void clear() noexcept; +}; + +template +Stack::Stack(int size) : _size(size), _top(-1) { + if (size <= 0) { + throw std::invalid_argument("Stack size must be positive"); + } + _data = new T[_size]; +} + +template +Stack::~Stack() { + delete[] _data; +} + +template +void Stack::push(const T& val) { + if (is_full()) { + throw std::logic_error("Stack is full"); + } + _data[++_top] = val; +} + +template +void Stack::pop() { + if (is_empty()) { + throw std::logic_error("Stack is empty"); + } + --_top; +} + +template +T Stack::top() const { + if (is_empty()) { + throw std::logic_error("Stack is empty"); + } + return _data[_top]; +} + +template +bool Stack::is_empty() const noexcept { + return _top == -1; +} + +template +bool Stack::is_full() const noexcept { + return _top == _size - 1; +} + +template +void Stack::clear() noexcept { + _top = -1; +} + +#endif // STACK_H \ No newline at end of file diff --git a/tests/test_algorithms.cpp b/tests/test_algorithms.cpp new file mode 100644 index 00000000..3ef27dd9 --- /dev/null +++ b/tests/test_algorithms.cpp @@ -0,0 +1,35 @@ +#include +#include "algorithms.h" +#include "stack.h" +TEST(AlgorithmsTest, 1) { + EXPECT_TRUE(check_algorithms("()")); + EXPECT_TRUE(check_algorithms("{}")); + EXPECT_TRUE(check_algorithms("[]")); +} + +TEST(AlgorithmsTest, 2) { + EXPECT_TRUE(check_algorithms("({[]})")); + EXPECT_TRUE(check_algorithms("{[()]}")); + EXPECT_TRUE(check_algorithms("({})[]")); +} + +TEST(AlgorithmsTest, 3) { + EXPECT_FALSE(check_algorithms("(")); + EXPECT_FALSE(check_algorithms(")")); + EXPECT_FALSE(check_algorithms("{[}")); + EXPECT_FALSE(check_algorithms("({[}])")); +} +TEST(AlgorithmsTest, 4) { + EXPECT_FALSE(check_algorithms("([)]")); + EXPECT_FALSE(check_algorithms("{(})")); +} +TEST(AlgorithmsTest, 5) { + EXPECT_TRUE(check_algorithms("()[]{}")); + EXPECT_TRUE(check_algorithms("({[]})[]{}")); +} + +TEST(AlgorithmsTest, 6) { + EXPECT_FALSE(check_algorithms("())")); + EXPECT_FALSE(check_algorithms("{[}]")); + EXPECT_FALSE(check_algorithms("(((")); +} \ No newline at end of file diff --git a/tests/test_stack.cpp b/tests/test_stack.cpp new file mode 100644 index 00000000..a33c8903 --- /dev/null +++ b/tests/test_stack.cpp @@ -0,0 +1,132 @@ +#include +#include "stack.h" +#include +TEST(StackTest, Constructor) { + Stack stack(10); + EXPECT_TRUE(stack.is_empty()); + EXPECT_FALSE(stack.is_full()); +} + +TEST(StackTest, InvalidSize) { + EXPECT_THROW(Stack stack(0), std::invalid_argument); + EXPECT_THROW(Stack stack(-5), std::invalid_argument); +} + +TEST(StackTest, Push) { + Stack stack(5); + + stack.push(1); + EXPECT_FALSE(stack.is_empty()); + EXPECT_EQ(stack.top(), 1); + + stack.push(2); + EXPECT_EQ(stack.top(), 2); + + stack.push(3); + EXPECT_EQ(stack.top(), 3); +} + +TEST(StackTest, Pop) { + Stack stack(5); + stack.push(1); + stack.push(2); + stack.push(3); + + EXPECT_EQ(stack.top(), 3); + stack.pop(); + EXPECT_EQ(stack.top(), 2); + stack.pop(); + EXPECT_EQ(stack.top(), 1); + stack.pop(); + EXPECT_TRUE(stack.is_empty()); +} + +TEST(StackTest, PopEmptyStack) { + Stack stack(5); + EXPECT_THROW(stack.pop(), std::logic_error); + + stack.push(1); + stack.pop(); + EXPECT_THROW(stack.pop(), std::logic_error); +} + +TEST(StackTest, TopEmptyStack) { + Stack stack(5); + EXPECT_THROW(stack.top(), std::logic_error); +} + +TEST(StackTest, Overflow) { + Stack stack(3); + stack.push(1); + stack.push(2); + stack.push(3); + EXPECT_TRUE(stack.is_full()); + EXPECT_THROW(stack.push(4), std::logic_error); +} + +TEST(StackTest, IsEmpty) { + Stack stack(5); + EXPECT_TRUE(stack.is_empty()); + stack.push(1); + EXPECT_FALSE(stack.is_empty()); + stack.pop(); + EXPECT_TRUE(stack.is_empty()); +} + +TEST(StackTest, IsFull) { + Stack stack(2); + EXPECT_FALSE(stack.is_full()); + stack.push(1); + EXPECT_FALSE(stack.is_full()); + stack.push(2); + EXPECT_TRUE(stack.is_full()); + stack.pop(); + EXPECT_FALSE(stack.is_full()); +} + +TEST(StackTest, Clear) { + Stack stack(5); + for (int i = 0; i < 4; i++) { + stack.push(i + 1); + } + EXPECT_FALSE(stack.is_empty()); + stack.clear(); + EXPECT_TRUE(stack.is_empty()); + EXPECT_THROW(stack.top(), std::logic_error); +} + +TEST(StackTest, SequenceOperations) { + Stack stack(10); + stack.push(1); + stack.push(2); + EXPECT_EQ(stack.top(), 2); + stack.pop(); + EXPECT_EQ(stack.top(), 1); + stack.push(3); + EXPECT_EQ(stack.top(), 3); +} + +TEST(StackTest, DifferentDataTypes) { + Stack doubleStack(5); + doubleStack.push(3.14); + doubleStack.push(2.71); + EXPECT_DOUBLE_EQ(doubleStack.top(), 2.71); + Stack stringStack(5); + stringStack.push("hello"); + stringStack.push("world"); + EXPECT_EQ(stringStack.top(), "world"); +} + +TEST(StackTest, LastInFirstOut) { + Stack stack(5); + stack.push(1); + stack.push(2); + stack.push(3); + EXPECT_EQ(stack.top(), 3); + stack.pop(); + EXPECT_EQ(stack.top(), 2); + stack.pop(); + EXPECT_EQ(stack.top(), 1); + stack.pop(); + EXPECT_TRUE(stack.is_empty()); +} \ No newline at end of file From d046f13c8b0a11483b0bd6751aed7854df5c7ec9 Mon Sep 17 00:00:00 2001 From: mrskristinaa Date: Wed, 29 Oct 2025 11:42:14 +0300 Subject: [PATCH 06/23] added realization of class List with tests --- CMakeLists.txt | 3 +- lib_list/CMakeLists.txt | 1 + lib_list/list.cpp | 0 lib_list/list.h | 215 ++++++++++++++++++++++++++++++++++++++ tests/test_list.cpp | 224 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 442 insertions(+), 1 deletion(-) create mode 100644 lib_list/CMakeLists.txt create mode 100644 lib_list/list.cpp create mode 100644 lib_list/list.h create mode 100644 tests/test_list.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ed05fc1..a752a16b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,8 @@ include(cmake/function.cmake) # подхватываем функции, # для простоты мы объединили наборы команд для создания статической библиотеки # и для создания исполняемого проекта в отдельные функции -add_subdirectory(lib_easy_example) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example +add_subdirectory(lib_easy_example) +add_subdirectory(lib_list) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example add_subdirectory(main) # подключаем дополнительный CMakeLists.txt из подкаталога с именем main option(BTEST "build test?" ON) # указываем подключаем ли google-тесты (ON или YES) или нет (OFF или NO) diff --git a/lib_list/CMakeLists.txt b/lib_list/CMakeLists.txt new file mode 100644 index 00000000..148b539a --- /dev/null +++ b/lib_list/CMakeLists.txt @@ -0,0 +1 @@ +create_project_lib(List) \ No newline at end of file diff --git a/lib_list/list.cpp b/lib_list/list.cpp new file mode 100644 index 00000000..e69de29b diff --git a/lib_list/list.h b/lib_list/list.h new file mode 100644 index 00000000..928c7bcd --- /dev/null +++ b/lib_list/list.h @@ -0,0 +1,215 @@ +#pragma once +template +struct Node { + T value; + Node* next; + Node(T value_, Node* next_ = nullptr); +}; +template +class List { + Node* _head, * _tail; + int _count; +public: + List() :_head(nullptr), _tail(nullptr), _count(0) {} + List(const List& other); + ~List(); + + void push_front(const T& val) noexcept; + void push_back(const T& val) noexcept; + void insert(int pos, const T& val); + void insert(Node* node, const T& val); + + void pop_front(); + void pop_back(); + void erase(int pos); + void erase(Node* node); + void clear(); + + bool is_empty(); + Node* find(const T& val); +}; + +template +Node::Node(T value_, Node* next_) : value(value_), next(next_) {} + +template +List::List(const List& other) : _head(nullptr), _tail(nullptr), _count(0) { + Node* current = other._head; + while (current != nullptr) { + push_back(current->value); + current = current->next; + } +} + +template +List::~List() { + clear(); +} + +template +void List::push_front(const T& val) noexcept { + Node* node = new Node(val, _head); + if (is_empty()) _tail = node; + _head = node; + _count++; +} + +template +void List::push_back(const T& val) noexcept { + Node* node = new Node(val); + if (is_empty()) { + _head = node; + _tail = node; + _count++; + return; + } + _tail->next = node; + _tail = node; + ++_count; +} + +template +void List::insert(Node* node, const T& val) { + if (node == nullptr) throw "Error: null node"; + Node* new_node = new Node(val, node->next); + node->next = new_node; + if (_tail == node) { + _tail = new_node; + } + _count++; +} + +template +void List::insert(int pos, const T& val) { + if (pos < 0 || pos > _count) throw "Error: position out of range"; + + if (pos == 0) { + push_front(val); + return; + } + else if (pos == _count) { + push_back(val); + return; + } + + int cur_pos = 0; + Node* cur = _head; + while (cur != nullptr) { + if (cur_pos == pos - 1) break; + cur_pos++; + cur = cur->next; + } + insert(cur, val); +} + +template +void List::pop_front() { + if (is_empty()) throw "Error: list is empty"; + + Node* temp = _head; + _head = _head->next; + delete temp; + _count--; + + if (_head == nullptr) { + _tail = nullptr; + } +} + +template +void List::pop_back() { + if (is_empty()) throw "Error: list is empty"; + + if (_head == _tail) { + delete _head; + _head = _tail = nullptr; + _count = 0; + return; + } + + Node* current = _head; + while (current->next != _tail) { + current = current->next; + } + + delete _tail; + _tail = current; + _tail->next = nullptr; + _count--; +} + +template +void List::erase(Node* node) { + if (node == nullptr || is_empty()) throw "Error: invalid node or empty list"; + + if (node == _head) { + pop_front(); + return; + } + + Node* prev = _head; + while (prev != nullptr && prev->next != node) { + prev = prev->next; + } + + if (prev == nullptr) throw "Error: node not found in list"; + + prev->next = node->next; + if (node == _tail) { + _tail = prev; + } + + delete node; + _count--; +} + +template +void List::erase(int pos) { + if (pos < 0 || pos >= _count) throw "Error: position out of range"; + + if (pos == 0) { + pop_front(); + return; + } + + int cur_pos = 0; + Node* cur = _head; + while (cur_pos < pos - 1) { + cur_pos++; + cur = cur->next; + } + + Node* toDelete = cur->next; + cur->next = toDelete->next; + + if (toDelete == _tail) { + _tail = cur; + } + + delete toDelete; + _count--; +} + +template +void List::clear() { + while (!is_empty()) { + pop_front(); + } +} + +template +bool List::is_empty() { + return _head == nullptr; +} + +template +Node* List::find(const T& val) { + Node* current = _head; + while (current != nullptr) { + if (current->value == val) { + return current; + } + current = current->next; + } + return nullptr; +} \ No newline at end of file diff --git a/tests/test_list.cpp b/tests/test_list.cpp new file mode 100644 index 00000000..212b16ba --- /dev/null +++ b/tests/test_list.cpp @@ -0,0 +1,224 @@ +#include +#include "List.h" + +TEST(ListTest, DefaultConstructor) { + List list; + EXPECT_TRUE(list.is_empty()); +} + +TEST(ListTest, PushFront) { + List list; + list.push_front(3); + list.push_front(2); + list.push_front(1); + + EXPECT_FALSE(list.is_empty()); +} + +TEST(ListTest, PushBack) { + List list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + + EXPECT_FALSE(list.is_empty()); +} + +TEST(ListTest, PopFront) { + List list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + list.pop_front(); + +} + +TEST(ListTest, PopBack) { + List list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + list.pop_back(); +} + +TEST(ListTest, PopFrontSingleElement) { + List list; + list.push_back(1); + list.pop_front(); + EXPECT_TRUE(list.is_empty()); +} + +TEST(ListTest, PopBackSingleElement) { + List list; + list.push_back(1); + list.pop_back(); + EXPECT_TRUE(list.is_empty()); +} + +TEST(ListTest, InsertAtPosition) { + List list; + list.push_back(1); + list.push_back(3); + list.insert(1, 2); +} + +TEST(ListTest, InsertAtBeginning) { + List list; + list.push_back(2); + list.push_back(3); + list.insert(0, 1); +} + +TEST(ListTest, InsertAtEnd) { + List list; + list.push_back(1); + list.push_back(2); + list.insert(2, 3); +} + +TEST(ListTest, InsertAtInvalidPosition) { + List list; + list.push_back(1); + EXPECT_THROW(list.insert(5, 2), const char*); +} + +TEST(ListTest, EraseByPosition) { + List list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + list.erase(1); +} + +TEST(ListTest, EraseFirstElement) { + List list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + list.erase(0); +} + +TEST(ListTest, EraseLastElement) { + List list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + list.erase(2); +} + +TEST(ListTest, EraseInvalidPosition) { + List list; + list.push_back(1); + EXPECT_THROW(list.erase(5), const char*); +} + +TEST(ListTest, EraseEmptyList) { + List list; + EXPECT_THROW(list.erase(0), const char*); +} + +TEST(ListTest, FindExistingElement) { + List list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + Node* found = list.find(2); + EXPECT_NE(found, nullptr); + EXPECT_EQ(found->value, 2); +} + +TEST(ListTest, FindNonExistingElement) { + List list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + Node* found = list.find(5); + EXPECT_EQ(found, nullptr); +} + +TEST(ListTest, FindInEmptyList) { + List list; + Node* found = list.find(1); + EXPECT_EQ(found, nullptr); +} + +TEST(ListTest, ClearList) { + List list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + list.clear(); + EXPECT_TRUE(list.is_empty()); +} + +TEST(ListTest, ClearEmptyList) { + List list; + list.clear(); + EXPECT_TRUE(list.is_empty()); +} + +TEST(ListTest, CopyConstructor) { + List original; + original.push_back(1); + original.push_back(2); + original.push_back(3); + List copy(original); + original.pop_front(); +} + +TEST(ListTest, CopyConstructorEmptyList) { + List original; + List copy(original); + EXPECT_TRUE(copy.is_empty()); +} + +TEST(ListTest, Destructor) { + { + List list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + } +} + +TEST(ListTest, MultipleDataTypes) { + List stringList; + stringList.push_back("hello"); + stringList.push_back("world"); + List doubleList; + doubleList.push_back(3.14); + doubleList.push_back(2.71); + EXPECT_FALSE(stringList.is_empty()); + EXPECT_FALSE(doubleList.is_empty()); +} + +TEST(ListTest, InsertAfterNode) { + List list; + list.push_back(1); + list.push_back(3); + Node* first = list.find(1); + ASSERT_NE(first, nullptr); + list.insert(first, 2); +} + +TEST(ListTest, EraseByNode) { + List list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + Node* nodeToDelete = list.find(2); + ASSERT_NE(nodeToDelete, nullptr); + list.erase(nodeToDelete); +} + +TEST(ListTest, ComplexOperationsSequence) { + List list; + list.push_front(2); + list.push_back(3); + list.push_front(1); + list.insert(1, 4); + list.pop_back(); + list.pop_front(); + list.erase(0); + EXPECT_FALSE(list.is_empty()); +} \ No newline at end of file From fed05aeb201376bf7b24310440c8648de85ab7c6 Mon Sep 17 00:00:00 2001 From: mrskristinaa Date: Wed, 29 Oct 2025 12:29:52 +0300 Subject: [PATCH 07/23] added realization of class List with class Iterator --- lib_list/list.h | 50 +++++++++++++++++++++++++++++++++++++++++++++ tests/test_list.cpp | 43 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 91 insertions(+), 2 deletions(-) diff --git a/lib_list/list.h b/lib_list/list.h index 928c7bcd..22943ed9 100644 --- a/lib_list/list.h +++ b/lib_list/list.h @@ -27,6 +27,21 @@ class List { bool is_empty(); Node* find(const T& val); + class Iterator { + Node* current; + public: + Iterator() : current(nullptr) {} + Iterator(Node* pos) : current(pos) {} + Iterator(const Iterator& other) : current(other.current) {} + + Iterator& operator=(const Iterator& other); + T& operator*(); + bool operator!=(const Iterator& other); + Iterator operator++(int); + Iterator& operator++(); + }; + Iterator begin() { return Iterator(_head); } + Iterator end() { return Iterator(nullptr); } }; template @@ -212,4 +227,39 @@ Node* List::find(const T& val) { current = current->next; } return nullptr; +} + + +template +typename List::Iterator& List::Iterator::operator=(const Iterator& other) { + if (this != &other) { + current = other.current; + } + return *this; +} + +template +T& List::Iterator::operator*() { + if (current == nullptr) throw "Error: dereferencing null iterator"; + return current->value; +} + +template +bool List::Iterator::operator!=(const Iterator& other) { + return current != other.current; +} + +template +typename List::Iterator List::Iterator::operator++(int) { + if (current == nullptr) throw "Error: incrementing null iterator"; + Iterator temp = *this; + current = current->next; + return temp; +} + +template +typename List::Iterator& List::Iterator::operator++() { + if (current == nullptr) throw "Error: incrementing null iterator"; + current = current->next; + return *this; } \ No newline at end of file diff --git a/tests/test_list.cpp b/tests/test_list.cpp index 212b16ba..648cf232 100644 --- a/tests/test_list.cpp +++ b/tests/test_list.cpp @@ -1,5 +1,5 @@ #include -#include "List.h" +#include "list.h" TEST(ListTest, DefaultConstructor) { List list; @@ -221,4 +221,43 @@ TEST(ListTest, ComplexOperationsSequence) { list.pop_front(); list.erase(0); EXPECT_FALSE(list.is_empty()); -} \ No newline at end of file +} +//TEST(TestLibLib, can_iterate) { +// List list; +// for (int i = 0; i < 10; i++) { +// list.push_back(i + 1); +// } +// Node* cur = list._head; +// while (cur != nullptr) { +// std::cout << cur->data << " "; +// cur = cur->next; +// } +// std::vector vec = { 1,4,5,6 }; +// for (std::vector::iterator it = vec.begin(); it != vec.end(); it++) { +// std::cout << *it << " "; +// } +//} +TEST(ListTest, can_read) { + Listlist; + for (int i = 0; i < 10; i++) { + list.push_back(i + 1); + } + int expected_val = 1; + for (List::Iterator it = list.begin(); it != list.end(); it++) { + expected_val++; + } +} +TEST(ListTest, can_write) { + Listlist; + int expected_val = 1; + for (List::Iterator it = list.begin(); it != list.end(); it++) { + EXPECT_EQ(*it, expected_val); + expected_val++; + } +} +TEST(ListTest, is_empty) { + Listlist; + for (List::Iterator it = list.begin(); it != list.end(); it++) { + *it = 0; + } +} From 545ebd3860bbe39cbee821430826232910599c7e Mon Sep 17 00:00:00 2001 From: mrskristinaa Date: Wed, 29 Oct 2025 12:36:31 +0300 Subject: [PATCH 08/23] the test in the Iterator class has been corrected --- tests/test_list.cpp | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/tests/test_list.cpp b/tests/test_list.cpp index 648cf232..14b4320c 100644 --- a/tests/test_list.cpp +++ b/tests/test_list.cpp @@ -222,21 +222,7 @@ TEST(ListTest, ComplexOperationsSequence) { list.erase(0); EXPECT_FALSE(list.is_empty()); } -//TEST(TestLibLib, can_iterate) { -// List list; -// for (int i = 0; i < 10; i++) { -// list.push_back(i + 1); -// } -// Node* cur = list._head; -// while (cur != nullptr) { -// std::cout << cur->data << " "; -// cur = cur->next; -// } -// std::vector vec = { 1,4,5,6 }; -// for (std::vector::iterator it = vec.begin(); it != vec.end(); it++) { -// std::cout << *it << " "; -// } -//} + TEST(ListTest, can_read) { Listlist; for (int i = 0; i < 10; i++) { @@ -244,6 +230,12 @@ TEST(ListTest, can_read) { } int expected_val = 1; for (List::Iterator it = list.begin(); it != list.end(); it++) { + *it = expected_val; + expected_val++; + } + expected_val = 1; + for (List::Iterator it = list.begin(); it != list.end(); it++) { + EXPECT_EQ(*it, expected_val); expected_val++; } } From 812805fac655dc15643ae7ee46f186e4bae9bcf7 Mon Sep 17 00:00:00 2001 From: mrskristinaa Date: Tue, 4 Nov 2025 23:54:45 +0300 Subject: [PATCH 09/23] tests have been corrected --- lib_list/list.h | 1 + tests/test_list.cpp | 92 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 72 insertions(+), 21 deletions(-) diff --git a/lib_list/list.h b/lib_list/list.h index 22943ed9..ca4e146a 100644 --- a/lib_list/list.h +++ b/lib_list/list.h @@ -39,6 +39,7 @@ class List { bool operator!=(const Iterator& other); Iterator operator++(int); Iterator& operator++(); + bool operator==(const Iterator& other) { return current == other.current; } }; Iterator begin() { return Iterator(_head); } Iterator end() { return Iterator(nullptr); } diff --git a/tests/test_list.cpp b/tests/test_list.cpp index 14b4320c..de55bf62 100644 --- a/tests/test_list.cpp +++ b/tests/test_list.cpp @@ -223,33 +223,83 @@ TEST(ListTest, ComplexOperationsSequence) { EXPECT_FALSE(list.is_empty()); } -TEST(ListTest, can_read) { - Listlist; - for (int i = 0; i < 10; i++) { - list.push_back(i + 1); - } - int expected_val = 1; - for (List::Iterator it = list.begin(); it != list.end(); it++) { - *it = expected_val; - expected_val++; +//TEST(ListTest, can_read) { +// Listlist; +// for (int i = 0; i < 10; i++) { +// list.push_back(i + 1); +// } +// int expected_val = 1; +// for (List::Iterator it = list.begin(); it != list.end(); it++) { +// *it = expected_val; +// expected_val++; +// } +// expected_val = 1; +// for (List::Iterator it = list.begin(); it != list.end(); it++) { +// EXPECT_EQ(*it, expected_val); +// expected_val++; +// } +//} +//TEST(ListTest, can_write) { +// Listlist; +// int expected_val = 1; +// for (List::Iterator it = list.begin(); it != list.end(); it++) { +// EXPECT_EQ(*it, expected_val); +// expected_val++; +// } +//} +//TEST(ListTest, is_empty) { +// Listlist; +// for (List::Iterator it = list.begin(); it != list.end(); it++) { +// *it = 0; +// } +//} + +TEST(IteratorTest, ReadWithPostIncrement) { + List list; + for (int i = 0; i < 5; i++) { + list.push_back(i * 3 + 1); } - expected_val = 1; + std::vector result; for (List::Iterator it = list.begin(); it != list.end(); it++) { - EXPECT_EQ(*it, expected_val); - expected_val++; + result.push_back(*it); } + std::vector expected = { 1, 4, 7, 10, 13 }; + EXPECT_EQ(result, expected); } -TEST(ListTest, can_write) { - Listlist; - int expected_val = 1; - for (List::Iterator it = list.begin(); it != list.end(); it++) { - EXPECT_EQ(*it, expected_val); - expected_val++; + +TEST(IteratorTest, WriteWithPreIncrement) { + List list; + for (int i = 0; i < 5; i++) { + list.push_back(0); } + int new_value = 5; + for (List::Iterator it = list.begin(); it != list.end(); ++it) { + *it = new_value; + new_value *= 2; + } + std::vector result; + for (List::Iterator it = list.begin(); it != list.end(); ++it) { + result.push_back(*it); + } + std::vector expected = { 5, 10, 20, 40, 80 }; + EXPECT_EQ(result, expected); } -TEST(ListTest, is_empty) { - Listlist; + +TEST(IteratorTest, EmptyListWithBothIncrementTypes) { + List list; + List::Iterator begin = list.begin(); + List::Iterator end = list.end(); + EXPECT_TRUE(begin == end); + EXPECT_FALSE(begin != end); + int iteration_count_post = 0; for (List::Iterator it = list.begin(); it != list.end(); it++) { - *it = 0; + iteration_count_post++; + } + EXPECT_EQ(iteration_count_post, 0); + int iteration_count_pre = 0; + for (List::Iterator it = list.begin(); it != list.end(); ++it) { + iteration_count_pre++; } + EXPECT_EQ(iteration_count_pre, 0); } + From 5208f6a20db21eab02c42794eadeceafaf591981 Mon Sep 17 00:00:00 2001 From: mrskristinaa Date: Wed, 5 Nov 2025 11:38:23 +0300 Subject: [PATCH 10/23] added realization of optimization DSU --- CMakeLists.txt | 3 +- lib_dsu/CMakeLists.txt | 1 + lib_dsu/dsu.cpp | 0 lib_dsu/dsu.h | 40 ++++++++++++++++++++ tests/test_dsu.cpp | 83 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 lib_dsu/CMakeLists.txt create mode 100644 lib_dsu/dsu.cpp create mode 100644 lib_dsu/dsu.h create mode 100644 tests/test_dsu.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ed05fc1..07201155 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,8 @@ include(cmake/function.cmake) # подхватываем функции, # для простоты мы объединили наборы команд для создания статической библиотеки # и для создания исполняемого проекта в отдельные функции -add_subdirectory(lib_easy_example) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example +add_subdirectory(lib_easy_example) +add_subdirectory(lib_dsu) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example add_subdirectory(main) # подключаем дополнительный CMakeLists.txt из подкаталога с именем main option(BTEST "build test?" ON) # указываем подключаем ли google-тесты (ON или YES) или нет (OFF или NO) diff --git a/lib_dsu/CMakeLists.txt b/lib_dsu/CMakeLists.txt new file mode 100644 index 00000000..424d2417 --- /dev/null +++ b/lib_dsu/CMakeLists.txt @@ -0,0 +1 @@ +create_project_lib(DSU) \ No newline at end of file diff --git a/lib_dsu/dsu.cpp b/lib_dsu/dsu.cpp new file mode 100644 index 00000000..e69de29b diff --git a/lib_dsu/dsu.h b/lib_dsu/dsu.h new file mode 100644 index 00000000..d11c5d13 --- /dev/null +++ b/lib_dsu/dsu.h @@ -0,0 +1,40 @@ +class DSU { + int* _parent; + int _size; + int* _rank; +public: + DSU(int size); + void unite(int, int); + int find(int); + ~DSU(); +}; +DSU::DSU(int size) : _size(size) { + _parent = new int[_size]; + _rank = new int[size]; + for (int i = 0; i < _size; i++) { + _parent[i] = i; + _rank[i] = 0; + } +} +DSU:: ~DSU() { + delete[] _parent; +} +int DSU::find(int x) { + if (_parent[x] == x) { + return x; + } + else { + return find(_parent[x]); + } +} +void DSU::unite(int x1, int x2) { + if (_rank[x1] < _rank[x2]) { + _parent[x1] = find(x2); + } + else { + if (_rank[x1] == _rank[x2]) { + _rank[x1]++; + } + _parent[x2] = find(x1); + } +} \ No newline at end of file diff --git a/tests/test_dsu.cpp b/tests/test_dsu.cpp new file mode 100644 index 00000000..d95d7945 --- /dev/null +++ b/tests/test_dsu.cpp @@ -0,0 +1,83 @@ +#include +#include "dsu.h" +TEST(DSUBasicTest, Initialization) { + DSU dsu(5); + EXPECT_EQ(dsu.find(0), 0); + EXPECT_EQ(dsu.find(1), 1); + EXPECT_EQ(dsu.find(2), 2); + EXPECT_EQ(dsu.find(3), 3); + EXPECT_EQ(dsu.find(4), 4); +} + +TEST(DSUBasicTest, SimpleUnion) { + DSU dsu(3); + dsu.unite(0, 1); + int root0 = dsu.find(0); + int root1 = dsu.find(1); + int root2 = dsu.find(2); + EXPECT_EQ(root0, root1); + EXPECT_NE(root0, root2); +} + +TEST(DSUBasicTest, MultipleUnions) { + DSU dsu(5); + dsu.unite(0, 1); + dsu.unite(2, 3); + EXPECT_EQ(dsu.find(0), dsu.find(1)); + EXPECT_EQ(dsu.find(2), dsu.find(3)); + EXPECT_NE(dsu.find(0), dsu.find(2)); + EXPECT_NE(dsu.find(1), dsu.find(4)); +} + +TEST(DSUBasicTest, TransitiveConnection) { + DSU dsu(4); + dsu.unite(0, 1); + dsu.unite(1, 2); + dsu.unite(2, 3); + EXPECT_EQ(dsu.find(0), dsu.find(3)); + EXPECT_EQ(dsu.find(1), dsu.find(3)); +} + +TEST(DSUBasicTest, RankBehavior) { + DSU dsu(4); + dsu.unite(0, 1); + dsu.unite(2, 3); + int root1 = dsu.find(0); + int root2 = dsu.find(2); + dsu.unite(0, 2); + EXPECT_EQ(dsu.find(0), dsu.find(1)); + EXPECT_EQ(dsu.find(0), dsu.find(2)); + EXPECT_EQ(dsu.find(0), dsu.find(3)); +} + +TEST(DSUBasicTest, SelfUnion) { + DSU dsu(3); + dsu.unite(1, 1); + EXPECT_EQ(dsu.find(1), 1); +} + +TEST(DSUBasicTest, ChainUnion) { + DSU dsu(6); + dsu.unite(0, 1); + dsu.unite(1, 2); + dsu.unite(2, 3); + dsu.unite(3, 4); + EXPECT_EQ(dsu.find(0), dsu.find(4)); + EXPECT_NE(dsu.find(0), dsu.find(5)); +} + +TEST(DSUMemoryTest, LargeDSU) { + const int SIZE = 1000; + DSU dsu(SIZE); + for (int i = 2; i < SIZE; i += 2) { + dsu.unite(0, i); + } + for (int i = 3; i < SIZE; i += 2) { + dsu.unite(1, i); + } + EXPECT_EQ(dsu.find(0), dsu.find(2)); + EXPECT_EQ(dsu.find(0), dsu.find(4)); + EXPECT_EQ(dsu.find(1), dsu.find(3)); + EXPECT_EQ(dsu.find(1), dsu.find(5)); + EXPECT_NE(dsu.find(0), dsu.find(1)); +} \ No newline at end of file From 62abff0003f610c854cc998d26112b6253834117 Mon Sep 17 00:00:00 2001 From: mrskristinaa Date: Wed, 12 Nov 2025 12:22:10 +0300 Subject: [PATCH 11/23] added stack on list --- lib_list/stack.h | 82 +++++++++++++++++++++++++++++++++++++++++++++ tests/test_list.cpp | 44 ++++++++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 lib_list/stack.h diff --git a/lib_list/stack.h b/lib_list/stack.h new file mode 100644 index 00000000..ed33a054 --- /dev/null +++ b/lib_list/stack.h @@ -0,0 +1,82 @@ +#pragma once +#include "list.h" +#include +#ifndef STACK_LIST_H +#define STACK_LIST_H +template +class StackList { +private: + List* _list; +public: + StackList() { + _list = new List(); + } + StackList(const StackList& other) { + _list = new List(*other._list); + } + + + ~StackList() { + delete _list; + _list = nullptr; + } + + + StackList& operator=(const StackList& other) { + if (this != &other) { + delete _list; + _list = new List(*other._list); + } + return *this; + } + + void push(const T& val); + void pop(); + T top() const; + bool is_empty() const noexcept; + void clear() noexcept; + int size() const noexcept; +}; + +template +void StackList::push(const T& val) { + _list->push_front(val); +} + +template +void StackList::pop() { + if (is_empty()) { + throw std::logic_error("Stack is empty"); + } + _list->pop_front(); +} + +template +T StackList::top() const { + if (is_empty()) { + throw std::logic_error("Stack is empty"); + } + auto it = _list->begin(); + return *it; +} + +template +bool StackList::is_empty() const noexcept { + return _list->is_empty(); +} + +template +void StackList::clear() noexcept { + _list->clear(); +} + +template +int StackList::size() const noexcept { + int count = 0; + for (auto it = _list->begin(); it != _list->end(); ++it) { + count++; + } + return count; +} + +#endif // STACK_LIST_H \ No newline at end of file diff --git a/tests/test_list.cpp b/tests/test_list.cpp index de55bf62..859f3e6d 100644 --- a/tests/test_list.cpp +++ b/tests/test_list.cpp @@ -303,3 +303,47 @@ TEST(IteratorTest, EmptyListWithBothIncrementTypes) { EXPECT_EQ(iteration_count_pre, 0); } +#include +#include "stack.h" + +TEST(StackListWithDeleteTest, ConstructorDestructor) { + StackList* stack = new StackList(); + stack->push(1); + stack->push(2); + stack->push(3); + EXPECT_EQ(stack->size(), 3); + delete stack; +} + +TEST(StackListWithDeleteTest, CopyConstructor) { + StackList original; + original.push(1); + original.push(2); + + StackList copy(original); + EXPECT_EQ(copy.size(), 2); + EXPECT_EQ(copy.top(), 2); +} + +TEST(StackListWithDeleteTest, AssignmentOperator) { + StackList stack1; + stack1.push(10); + stack1.push(20); + + StackList stack2; + stack2 = stack1; + + EXPECT_EQ(stack2.size(), 2); + EXPECT_EQ(stack2.top(), 20); +} + +TEST(StackListWithDeleteTest, MemoryManagement) { + { + StackList stack; + for (int i = 0; i < 100; i++) { + stack.push(i); + } + + } +} + From 4543839f1078722619704bd03c78912019d24c5a Mon Sep 17 00:00:00 2001 From: mrskristinaa Date: Tue, 2 Dec 2025 15:00:59 +0300 Subject: [PATCH 12/23] tests added to Queue --- tests/test_queue.cpp | 130 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 tests/test_queue.cpp diff --git a/tests/test_queue.cpp b/tests/test_queue.cpp new file mode 100644 index 00000000..4fb53430 --- /dev/null +++ b/tests/test_queue.cpp @@ -0,0 +1,130 @@ +#include +#include "queue.h" +TEST(QueueTest, ConstructorWithSize) { + Queue q(5); + EXPECT_TRUE(q.is_empty()); + EXPECT_EQ(q.size(), 0); +} +TEST(QueueTest, DefaultConstructor) { + Queue q; + EXPECT_TRUE(q.is_empty()); + q.enqueue(1); + EXPECT_FALSE(q.is_empty()); +} +TEST(QueueTest, CopyConstructor) { + Queue q1(3); + q1.enqueue(1); + q1.enqueue(2); + Queue q2(q1); + EXPECT_EQ(q2.size(), 2); + EXPECT_EQ(q2.front(), 1); +} +TEST(QueueTest, AssignmentOperator) { + Queue q1(3); + q1.enqueue(10); + q1.enqueue(20); + Queue q2(2); + q2 = q1; + EXPECT_EQ(q2.size(), 2); + EXPECT_EQ(q2.front(), 10); +} +TEST(QueueTest, EnqueueMethod) { + Queue q(3); + q.enqueue(42); + EXPECT_EQ(q.size(), 1); + EXPECT_EQ(q.front(), 42); +} +TEST(QueueTest, DequeueMethod) { + Queue q(3); + q.enqueue(1); + q.enqueue(2); + q.dequeue(); + EXPECT_EQ(q.size(), 1); + EXPECT_EQ(q.front(), 2); +} +TEST(QueueTest, FrontMethod) { + Queue q(3); + q.enqueue(100); + EXPECT_EQ(q.front(), 100); +} +TEST(QueueTest, BackMethod) { + Queue q(3); + q.enqueue(1); + q.enqueue(2); + EXPECT_EQ(q.back(), 2); +} +TEST(QueueTest, IsEmptyMethod) { + Queue q(3); + EXPECT_TRUE(q.is_empty()); + q.enqueue(1); + EXPECT_FALSE(q.is_empty()); +} +TEST(QueueTest, IsFullMethod) { + Queue q(2); + EXPECT_FALSE(q.is_full()); + q.enqueue(1); + q.enqueue(2); + EXPECT_TRUE(q.is_full()); +} +TEST(QueueTest, SizeMethod) { + Queue q(3); + EXPECT_EQ(q.size(), 0); + q.enqueue(1); + EXPECT_EQ(q.size(), 1); +} +TEST(QueueTest, ClearMethod) { + Queue q(3); + q.enqueue(1); + q.enqueue(2); + q.clear(); + EXPECT_TRUE(q.is_empty()); + EXPECT_EQ(q.size(), 0); +} +TEST(QueueTest, ExceptionEmptyDequeue) { + Queue q(3); + EXPECT_THROW(q.dequeue(), std::logic_error); +} +TEST(QueueTest, ExceptionEmptyFront) { + Queue q(3); + EXPECT_THROW(q.front(), std::logic_error); +} +TEST(QueueTest, ExceptionEmptyBack) { + Queue q(3); + EXPECT_THROW(q.back(), std::logic_error); +} +TEST(QueueTest, ExceptionFullEnqueue) { + Queue q(2); + q.enqueue(1); + q.enqueue(2); + EXPECT_THROW(q.enqueue(3), std::logic_error); +} +TEST(QueueTest, ExceptionInvalidSize) { + EXPECT_THROW(Queue q(0), std::invalid_argument); + EXPECT_THROW(Queue q(-5), std::invalid_argument); +} +TEST(QueueTest, CircularBehavior) { + Queue q(3); + q.enqueue(1); + q.enqueue(2); + q.enqueue(3); + q.dequeue(); + q.enqueue(4); + EXPECT_EQ(q.front(), 2); + EXPECT_EQ(q.back(), 4); +} +TEST(QueueTest, DifferentTypes) { + Queue q1(3); + q1.enqueue(3.14); + EXPECT_DOUBLE_EQ(q1.front(), 3.14); + Queue q2(3); + q2.enqueue("test"); + EXPECT_EQ(q2.front(), "test"); +} +TEST(QueueTest, ReuseAfterClear) { + Queue q(3); + q.enqueue(1); + q.enqueue(2); + q.clear(); + q.enqueue(10); + EXPECT_EQ(q.front(), 10); +} \ No newline at end of file From 65a99329be2935a98a0cd7845ce5b28354cdbc13 Mon Sep 17 00:00:00 2001 From: mrskristinaa Date: Tue, 2 Dec 2025 15:52:31 +0300 Subject: [PATCH 13/23] Fix Stack implementation and add tests --- lib_stack/stack.h | 25 ++++++++++++++++++++++--- tests/test_stack.cpp | 36 ++++++++++++++++++------------------ 2 files changed, 40 insertions(+), 21 deletions(-) diff --git a/lib_stack/stack.h b/lib_stack/stack.h index d346b59f..ed44771b 100644 --- a/lib_stack/stack.h +++ b/lib_stack/stack.h @@ -11,8 +11,9 @@ class Stack { public: explicit Stack(int size = 100); + Stack(const Stack& other); ~Stack(); - + Stack& operator=(const Stack& other); void push(const T& val); void pop(); inline T top() const; @@ -28,12 +29,30 @@ Stack::Stack(int size) : _size(size), _top(-1) { } _data = new T[_size]; } - +template +Stack::Stack(const Stack& other) : _size(other._size), _top(other._top) { + _data = new T[_size]; + for (int i = 0; i <= _top; i++) { + _data[i] = other._data[i]; + } +} template Stack::~Stack() { delete[] _data; } - +template +Stack& Stack::operator=(const Stack& other) { + if (this != &other) { + delete[] _data; + _size = other._size; + _top = other._top; + _data = new T[_size]; + for (int i = 0; i <= _top; i++) { + _data[i] = other._data[i]; + } + } + return *this; +} template void Stack::push(const T& val) { if (is_full()) { diff --git a/tests/test_stack.cpp b/tests/test_stack.cpp index a33c8903..a5a9ae71 100644 --- a/tests/test_stack.cpp +++ b/tests/test_stack.cpp @@ -1,37 +1,47 @@ #include -#include "stack.h" +#include "../lib_stack/stack.h" #include TEST(StackTest, Constructor) { Stack stack(10); EXPECT_TRUE(stack.is_empty()); EXPECT_FALSE(stack.is_full()); } - +TEST(StackTest, CopyConstructor) { + Stack original(5); + original.push(1); + original.push(2); + Stack copy(original); + EXPECT_EQ(copy.top(), 2); + copy.pop(); + EXPECT_EQ(copy.top(), 1); +} +TEST(StackTest, AssignmentOperator) { + Stack stack1(5); + stack1.push(10); + stack1.push(20); + Stack stack2(3); + stack2 = stack1; + EXPECT_EQ(stack2.top(), 20); +} TEST(StackTest, InvalidSize) { EXPECT_THROW(Stack stack(0), std::invalid_argument); EXPECT_THROW(Stack stack(-5), std::invalid_argument); } - TEST(StackTest, Push) { Stack stack(5); - stack.push(1); EXPECT_FALSE(stack.is_empty()); EXPECT_EQ(stack.top(), 1); - stack.push(2); EXPECT_EQ(stack.top(), 2); - stack.push(3); EXPECT_EQ(stack.top(), 3); } - TEST(StackTest, Pop) { Stack stack(5); stack.push(1); stack.push(2); stack.push(3); - EXPECT_EQ(stack.top(), 3); stack.pop(); EXPECT_EQ(stack.top(), 2); @@ -40,21 +50,17 @@ TEST(StackTest, Pop) { stack.pop(); EXPECT_TRUE(stack.is_empty()); } - TEST(StackTest, PopEmptyStack) { Stack stack(5); EXPECT_THROW(stack.pop(), std::logic_error); - stack.push(1); stack.pop(); EXPECT_THROW(stack.pop(), std::logic_error); } - TEST(StackTest, TopEmptyStack) { Stack stack(5); EXPECT_THROW(stack.top(), std::logic_error); } - TEST(StackTest, Overflow) { Stack stack(3); stack.push(1); @@ -63,7 +69,6 @@ TEST(StackTest, Overflow) { EXPECT_TRUE(stack.is_full()); EXPECT_THROW(stack.push(4), std::logic_error); } - TEST(StackTest, IsEmpty) { Stack stack(5); EXPECT_TRUE(stack.is_empty()); @@ -72,7 +77,6 @@ TEST(StackTest, IsEmpty) { stack.pop(); EXPECT_TRUE(stack.is_empty()); } - TEST(StackTest, IsFull) { Stack stack(2); EXPECT_FALSE(stack.is_full()); @@ -83,7 +87,6 @@ TEST(StackTest, IsFull) { stack.pop(); EXPECT_FALSE(stack.is_full()); } - TEST(StackTest, Clear) { Stack stack(5); for (int i = 0; i < 4; i++) { @@ -94,7 +97,6 @@ TEST(StackTest, Clear) { EXPECT_TRUE(stack.is_empty()); EXPECT_THROW(stack.top(), std::logic_error); } - TEST(StackTest, SequenceOperations) { Stack stack(10); stack.push(1); @@ -105,7 +107,6 @@ TEST(StackTest, SequenceOperations) { stack.push(3); EXPECT_EQ(stack.top(), 3); } - TEST(StackTest, DifferentDataTypes) { Stack doubleStack(5); doubleStack.push(3.14); @@ -116,7 +117,6 @@ TEST(StackTest, DifferentDataTypes) { stringStack.push("world"); EXPECT_EQ(stringStack.top(), "world"); } - TEST(StackTest, LastInFirstOut) { Stack stack(5); stack.push(1); From 4e759c3a165edd1254306a231b16dcbf43ae575a Mon Sep 17 00:00:00 2001 From: mrskristinaa Date: Tue, 2 Dec 2025 16:23:20 +0300 Subject: [PATCH 14/23] Fix List implementation and tests --- lib_list/list.h | 45 +++++-- tests/test_list.cpp | 319 +++++++------------------------------------- 2 files changed, 79 insertions(+), 285 deletions(-) diff --git a/lib_list/list.h b/lib_list/list.h index ca4e146a..12cacb8c 100644 --- a/lib_list/list.h +++ b/lib_list/list.h @@ -1,4 +1,5 @@ #pragma once +#include template struct Node { T value; @@ -12,6 +13,7 @@ class List { public: List() :_head(nullptr), _tail(nullptr), _count(0) {} List(const List& other); + List& operator=(const List& other); ~List(); void push_front(const T& val) noexcept; @@ -25,7 +27,8 @@ class List { void erase(Node* node); void clear(); - bool is_empty(); + bool is_empty() const; + int size() const noexcept; Node* find(const T& val); class Iterator { Node* current; @@ -56,7 +59,18 @@ List::List(const List& other) : _head(nullptr), _tail(nullptr), _count(0) { current = current->next; } } - +template +List& List::operator=(const List& other) { + if (this != &other) { + clear(); + Node* current = other._head; + while (current != nullptr) { + push_back(current->value); + current = current->next; + } + } + return *this; +} template List::~List() { clear(); @@ -86,7 +100,7 @@ void List::push_back(const T& val) noexcept { template void List::insert(Node* node, const T& val) { - if (node == nullptr) throw "Error: null node"; + if (node == nullptr) throw std::logic_error ("Error: null node"); Node* new_node = new Node(val, node->next); node->next = new_node; if (_tail == node) { @@ -97,7 +111,7 @@ void List::insert(Node* node, const T& val) { template void List::insert(int pos, const T& val) { - if (pos < 0 || pos > _count) throw "Error: position out of range"; + if (pos < 0 || pos > _count) throw std::logic_error ("Error: position out of range"); if (pos == 0) { push_front(val); @@ -120,7 +134,7 @@ void List::insert(int pos, const T& val) { template void List::pop_front() { - if (is_empty()) throw "Error: list is empty"; + if (is_empty()) throw std::logic_error ("Error: list is empty"); Node* temp = _head; _head = _head->next; @@ -134,7 +148,7 @@ void List::pop_front() { template void List::pop_back() { - if (is_empty()) throw "Error: list is empty"; + if (is_empty()) throw std::logic_error ("Error: list is empty"); if (_head == _tail) { delete _head; @@ -156,7 +170,7 @@ void List::pop_back() { template void List::erase(Node* node) { - if (node == nullptr || is_empty()) throw "Error: invalid node or empty list"; + if (node == nullptr || is_empty()) throw std::logic_error ("Error: invalid node or empty list"); if (node == _head) { pop_front(); @@ -168,7 +182,7 @@ void List::erase(Node* node) { prev = prev->next; } - if (prev == nullptr) throw "Error: node not found in list"; + if (prev == nullptr) throw std::logic_error ("Error: node not found in list"); prev->next = node->next; if (node == _tail) { @@ -181,7 +195,7 @@ void List::erase(Node* node) { template void List::erase(int pos) { - if (pos < 0 || pos >= _count) throw "Error: position out of range"; + if (pos < 0 || pos >= _count) throw std::logic_error ("Error: position out of range"); if (pos == 0) { pop_front(); @@ -214,10 +228,13 @@ void List::clear() { } template -bool List::is_empty() { +bool List::is_empty() const { return _head == nullptr; } - +template +int List::size() const noexcept { + return _count; +} template Node* List::find(const T& val) { Node* current = _head; @@ -241,7 +258,7 @@ typename List::Iterator& List::Iterator::operator=(const Iterator& other) template T& List::Iterator::operator*() { - if (current == nullptr) throw "Error: dereferencing null iterator"; + if (current == nullptr) throw std::logic_error ("Error: dereferencing null iterator"); return current->value; } @@ -252,7 +269,7 @@ bool List::Iterator::operator!=(const Iterator& other) { template typename List::Iterator List::Iterator::operator++(int) { - if (current == nullptr) throw "Error: incrementing null iterator"; + if (current == nullptr) throw std::logic_error ("Error: incrementing null iterator"); Iterator temp = *this; current = current->next; return temp; @@ -260,7 +277,7 @@ typename List::Iterator List::Iterator::operator++(int) { template typename List::Iterator& List::Iterator::operator++() { - if (current == nullptr) throw "Error: incrementing null iterator"; + if (current == nullptr) throw std::logic_error ("Error: incrementing null iterator"); current = current->next; return *this; } \ No newline at end of file diff --git a/tests/test_list.cpp b/tests/test_list.cpp index 859f3e6d..e290c067 100644 --- a/tests/test_list.cpp +++ b/tests/test_list.cpp @@ -1,228 +1,94 @@ #include -#include "list.h" - -TEST(ListTest, DefaultConstructor) { +#include "../lib_list/list.h" +TEST(ListTest, CreateEmpty) { List list; EXPECT_TRUE(list.is_empty()); + EXPECT_EQ(list.size(), 0); } +TEST(ListTest, CopyConstructor) { + List list1; + list1.push_back(1); + list1.push_back(2); -TEST(ListTest, PushFront) { - List list; - list.push_front(3); - list.push_front(2); - list.push_front(1); + List list2(list1); + EXPECT_EQ(list2.size(), 2); +} +TEST(ListTest, Assignment) { + List list1; + list1.push_back(10); + list1.push_back(20); - EXPECT_FALSE(list.is_empty()); + List list2; + list2 = list1; + EXPECT_EQ(list2.size(), 2); } -TEST(ListTest, PushBack) { +TEST(ListTest, DestructorWorks) { List list; list.push_back(1); list.push_back(2); - list.push_back(3); - - EXPECT_FALSE(list.is_empty()); } - -TEST(ListTest, PopFront) { +TEST(ListTest, PushElements) { List list; - list.push_back(1); - list.push_back(2); + list.push_front(2); list.push_back(3); - list.pop_front(); - + list.push_front(1); + EXPECT_EQ(list.size(), 3); } - -TEST(ListTest, PopBack) { +TEST(ListTest, PopElements) { List list; list.push_back(1); list.push_back(2); list.push_back(3); - list.pop_back(); -} - -TEST(ListTest, PopFrontSingleElement) { - List list; - list.push_back(1); list.pop_front(); - EXPECT_TRUE(list.is_empty()); -} - -TEST(ListTest, PopBackSingleElement) { - List list; - list.push_back(1); list.pop_back(); - EXPECT_TRUE(list.is_empty()); -} - -TEST(ListTest, InsertAtPosition) { - List list; - list.push_back(1); - list.push_back(3); - list.insert(1, 2); -} - -TEST(ListTest, InsertAtBeginning) { - List list; - list.push_back(2); - list.push_back(3); - list.insert(0, 1); -} - -TEST(ListTest, InsertAtEnd) { - List list; - list.push_back(1); - list.push_back(2); - list.insert(2, 3); -} - -TEST(ListTest, InsertAtInvalidPosition) { - List list; - list.push_back(1); - EXPECT_THROW(list.insert(5, 2), const char*); -} - -TEST(ListTest, EraseByPosition) { - List list; - list.push_back(1); - list.push_back(2); - list.push_back(3); - list.erase(1); -} - -TEST(ListTest, EraseFirstElement) { - List list; - list.push_back(1); - list.push_back(2); - list.push_back(3); - list.erase(0); -} - -TEST(ListTest, EraseLastElement) { - List list; - list.push_back(1); - list.push_back(2); - list.push_back(3); - list.erase(2); -} - -TEST(ListTest, EraseInvalidPosition) { - List list; - list.push_back(1); - EXPECT_THROW(list.erase(5), const char*); -} - -TEST(ListTest, EraseEmptyList) { - List list; - EXPECT_THROW(list.erase(0), const char*); + EXPECT_EQ(list.size(), 1); } - -TEST(ListTest, FindExistingElement) { +TEST(ListTest, InsertErase) { List list; list.push_back(1); - list.push_back(2); - list.push_back(3); - Node* found = list.find(2); - EXPECT_NE(found, nullptr); - EXPECT_EQ(found->value, 2); -} - -TEST(ListTest, FindNonExistingElement) { - List list; - list.push_back(1); - list.push_back(2); list.push_back(3); - Node* found = list.find(5); - EXPECT_EQ(found, nullptr); + list.insert(1, 2); + list.erase(0); + EXPECT_EQ(list.size(), 2); } - -TEST(ListTest, FindInEmptyList) { - List list; - Node* found = list.find(1); - EXPECT_EQ(found, nullptr); -} - -TEST(ListTest, ClearList) { +TEST(ListTest, Clear) { List list; list.push_back(1); list.push_back(2); - list.push_back(3); list.clear(); EXPECT_TRUE(list.is_empty()); } - -TEST(ListTest, ClearEmptyList) { +TEST(ListTest, Find) { List list; - list.clear(); - EXPECT_TRUE(list.is_empty()); -} - -TEST(ListTest, CopyConstructor) { - List original; - original.push_back(1); - original.push_back(2); - original.push_back(3); - List copy(original); - original.pop_front(); -} - -TEST(ListTest, CopyConstructorEmptyList) { - List original; - List copy(original); - EXPECT_TRUE(copy.is_empty()); -} - -TEST(ListTest, Destructor) { - { - List list; - list.push_back(1); - list.push_back(2); - list.push_back(3); - } -} - -TEST(ListTest, MultipleDataTypes) { - List stringList; - stringList.push_back("hello"); - stringList.push_back("world"); - List doubleList; - doubleList.push_back(3.14); - doubleList.push_back(2.71); - EXPECT_FALSE(stringList.is_empty()); - EXPECT_FALSE(doubleList.is_empty()); + list.push_back(10); + list.push_back(20); + Node* found = list.find(20); + EXPECT_NE(found, nullptr); } - -TEST(ListTest, InsertAfterNode) { +TEST(ListTest, Exceptions) { List list; + EXPECT_THROW(list.pop_front(), std::logic_error); list.push_back(1); - list.push_back(3); - Node* first = list.find(1); - ASSERT_NE(first, nullptr); - list.insert(first, 2); + EXPECT_THROW(list.erase(5), std::logic_error); } - -TEST(ListTest, EraseByNode) { +TEST(ListTest, Iterators) { List list; list.push_back(1); list.push_back(2); list.push_back(3); - Node* nodeToDelete = list.find(2); - ASSERT_NE(nodeToDelete, nullptr); - list.erase(nodeToDelete); + int sum = 0; + for (List::Iterator it = list.begin(); it != list.end(); ++it) { + sum += *it; + } + EXPECT_EQ(sum, 6); } - -TEST(ListTest, ComplexOperationsSequence) { - List list; - list.push_front(2); - list.push_back(3); - list.push_front(1); - list.insert(1, 4); - list.pop_back(); - list.pop_front(); - list.erase(0); - EXPECT_FALSE(list.is_empty()); +TEST(ListTest, DifferentTypes) { + List list; + list.push_back("hello"); + list.push_back("world"); + EXPECT_EQ(list.size(), 2); } - //TEST(ListTest, can_read) { // Listlist; // for (int i = 0; i < 10; i++) { @@ -254,96 +120,7 @@ TEST(ListTest, ComplexOperationsSequence) { // } //} -TEST(IteratorTest, ReadWithPostIncrement) { - List list; - for (int i = 0; i < 5; i++) { - list.push_back(i * 3 + 1); - } - std::vector result; - for (List::Iterator it = list.begin(); it != list.end(); it++) { - result.push_back(*it); - } - std::vector expected = { 1, 4, 7, 10, 13 }; - EXPECT_EQ(result, expected); -} -TEST(IteratorTest, WriteWithPreIncrement) { - List list; - for (int i = 0; i < 5; i++) { - list.push_back(0); - } - int new_value = 5; - for (List::Iterator it = list.begin(); it != list.end(); ++it) { - *it = new_value; - new_value *= 2; - } - std::vector result; - for (List::Iterator it = list.begin(); it != list.end(); ++it) { - result.push_back(*it); - } - std::vector expected = { 5, 10, 20, 40, 80 }; - EXPECT_EQ(result, expected); -} -TEST(IteratorTest, EmptyListWithBothIncrementTypes) { - List list; - List::Iterator begin = list.begin(); - List::Iterator end = list.end(); - EXPECT_TRUE(begin == end); - EXPECT_FALSE(begin != end); - int iteration_count_post = 0; - for (List::Iterator it = list.begin(); it != list.end(); it++) { - iteration_count_post++; - } - EXPECT_EQ(iteration_count_post, 0); - int iteration_count_pre = 0; - for (List::Iterator it = list.begin(); it != list.end(); ++it) { - iteration_count_pre++; - } - EXPECT_EQ(iteration_count_pre, 0); -} - -#include -#include "stack.h" -TEST(StackListWithDeleteTest, ConstructorDestructor) { - StackList* stack = new StackList(); - stack->push(1); - stack->push(2); - stack->push(3); - EXPECT_EQ(stack->size(), 3); - delete stack; -} - -TEST(StackListWithDeleteTest, CopyConstructor) { - StackList original; - original.push(1); - original.push(2); - - StackList copy(original); - EXPECT_EQ(copy.size(), 2); - EXPECT_EQ(copy.top(), 2); -} - -TEST(StackListWithDeleteTest, AssignmentOperator) { - StackList stack1; - stack1.push(10); - stack1.push(20); - - StackList stack2; - stack2 = stack1; - - EXPECT_EQ(stack2.size(), 2); - EXPECT_EQ(stack2.top(), 20); -} - -TEST(StackListWithDeleteTest, MemoryManagement) { - { - StackList stack; - for (int i = 0; i < 100; i++) { - stack.push(i); - } - - } -} From 081d932c30c50e487ea092aa96145d742530167b Mon Sep 17 00:00:00 2001 From: mrskristinaa Date: Tue, 2 Dec 2025 16:54:16 +0300 Subject: [PATCH 15/23] Fix DSU and update tests --- lib_dsu/dsu.h | 66 +++++++++++++++++++++------------------- tests/test_dsu.cpp | 75 ++++++++++++---------------------------------- 2 files changed, 54 insertions(+), 87 deletions(-) diff --git a/lib_dsu/dsu.h b/lib_dsu/dsu.h index d11c5d13..ae957591 100644 --- a/lib_dsu/dsu.h +++ b/lib_dsu/dsu.h @@ -1,40 +1,44 @@ +#pragma once class DSU { - int* _parent; - int _size; - int* _rank; + int* _parent; + int* _rank; + int _size; public: - DSU(int size); - void unite(int, int); - int find(int); - ~DSU(); + DSU(int size); + void unite(int, int); + int find(int); + ~DSU(); }; DSU::DSU(int size) : _size(size) { - _parent = new int[_size]; - _rank = new int[size]; - for (int i = 0; i < _size; i++) { - _parent[i] = i; - _rank[i] = 0; - } + _parent = new int[_size]; + _rank = new int[_size]; + for (int i = 0; i < _size; i++) { + _parent[i] = i; + _rank[i] = 0; + } } -DSU:: ~DSU() { - delete[] _parent; +DSU::~DSU() { + delete[] _parent; + delete[] _rank; } int DSU::find(int x) { - if (_parent[x] == x) { - return x; - } - else { - return find(_parent[x]); - } + if (_parent[x] != x) { + _parent[x] = find(_parent[x]); + } + return _parent[x]; } -void DSU::unite(int x1, int x2) { - if (_rank[x1] < _rank[x2]) { - _parent[x1] = find(x2); - } - else { - if (_rank[x1] == _rank[x2]) { - _rank[x1]++; - } - _parent[x2] = find(x1); - } +void DSU::unite(int x, int y) { + int rootX = find(x); + int rootY = find(y); + if (rootX == rootY) return; + if (_rank[rootX] < _rank[rootY]) { + _parent[rootX] = rootY; + } + else if (_rank[rootX] > _rank[rootY]) { + _parent[rootY] = rootX; + } + else { + _parent[rootY] = rootX; + _rank[rootX]++; + } } \ No newline at end of file diff --git a/tests/test_dsu.cpp b/tests/test_dsu.cpp index d95d7945..bf75e7b8 100644 --- a/tests/test_dsu.cpp +++ b/tests/test_dsu.cpp @@ -1,83 +1,46 @@ #include #include "dsu.h" -TEST(DSUBasicTest, Initialization) { +TEST(DSU_Simple, Create) { DSU dsu(5); EXPECT_EQ(dsu.find(0), 0); - EXPECT_EQ(dsu.find(1), 1); - EXPECT_EQ(dsu.find(2), 2); - EXPECT_EQ(dsu.find(3), 3); EXPECT_EQ(dsu.find(4), 4); } - -TEST(DSUBasicTest, SimpleUnion) { - DSU dsu(3); - dsu.unite(0, 1); - int root0 = dsu.find(0); - int root1 = dsu.find(1); - int root2 = dsu.find(2); - EXPECT_EQ(root0, root1); - EXPECT_NE(root0, root2); -} - -TEST(DSUBasicTest, MultipleUnions) { +TEST(DSU_Simple, UnionTwo) { DSU dsu(5); dsu.unite(0, 1); - dsu.unite(2, 3); EXPECT_EQ(dsu.find(0), dsu.find(1)); - EXPECT_EQ(dsu.find(2), dsu.find(3)); EXPECT_NE(dsu.find(0), dsu.find(2)); - EXPECT_NE(dsu.find(1), dsu.find(4)); } - -TEST(DSUBasicTest, TransitiveConnection) { +TEST(DSU_Simple, ChainUnion) { DSU dsu(4); dsu.unite(0, 1); dsu.unite(1, 2); dsu.unite(2, 3); EXPECT_EQ(dsu.find(0), dsu.find(3)); - EXPECT_EQ(dsu.find(1), dsu.find(3)); + EXPECT_EQ(dsu.find(1), dsu.find(2)); } - -TEST(DSUBasicTest, RankBehavior) { - DSU dsu(4); - dsu.unite(0, 1); - dsu.unite(2, 3); - int root1 = dsu.find(0); - int root2 = dsu.find(2); - dsu.unite(0, 2); - EXPECT_EQ(dsu.find(0), dsu.find(1)); - EXPECT_EQ(dsu.find(0), dsu.find(2)); - EXPECT_EQ(dsu.find(0), dsu.find(3)); -} - -TEST(DSUBasicTest, SelfUnion) { +TEST(DSU_Simple, SelfUnion) { DSU dsu(3); - dsu.unite(1, 1); - EXPECT_EQ(dsu.find(1), 1); + dsu.unite(1, 1); + EXPECT_EQ(dsu.find(1), 1); } - -TEST(DSUBasicTest, ChainUnion) { +TEST(DSU_Simple, MultipleSets) { DSU dsu(6); dsu.unite(0, 1); - dsu.unite(1, 2); dsu.unite(2, 3); - dsu.unite(3, 4); - EXPECT_EQ(dsu.find(0), dsu.find(4)); - EXPECT_NE(dsu.find(0), dsu.find(5)); + dsu.unite(4, 5); + EXPECT_EQ(dsu.find(0), dsu.find(1)); + EXPECT_EQ(dsu.find(2), dsu.find(3)); + EXPECT_EQ(dsu.find(4), dsu.find(5)); + EXPECT_NE(dsu.find(0), dsu.find(2)); + EXPECT_NE(dsu.find(2), dsu.find(4)); } - -TEST(DSUMemoryTest, LargeDSU) { - const int SIZE = 1000; - DSU dsu(SIZE); - for (int i = 2; i < SIZE; i += 2) { +TEST(DSU_Simple, LargeDSU) { + DSU dsu(100); + for (int i = 1; i < 100; i++) { dsu.unite(0, i); } - for (int i = 3; i < SIZE; i += 2) { - dsu.unite(1, i); + for (int i = 0; i < 100; i++) { + EXPECT_EQ(dsu.find(i), dsu.find(0)); } - EXPECT_EQ(dsu.find(0), dsu.find(2)); - EXPECT_EQ(dsu.find(0), dsu.find(4)); - EXPECT_EQ(dsu.find(1), dsu.find(3)); - EXPECT_EQ(dsu.find(1), dsu.find(5)); - EXPECT_NE(dsu.find(0), dsu.find(1)); } \ No newline at end of file From 1a298ba6a846035e1f576cf5597c6caa7a070b8d Mon Sep 17 00:00:00 2001 From: mrskristinaa Date: Tue, 2 Dec 2025 17:14:59 +0300 Subject: [PATCH 16/23] fix test list --- lib_list/list.h | 6 +++--- tests/test_list.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/lib_list/list.h b/lib_list/list.h index 12cacb8c..51eed6cd 100644 --- a/lib_list/list.h +++ b/lib_list/list.h @@ -39,10 +39,10 @@ class List { Iterator& operator=(const Iterator& other); T& operator*(); - bool operator!=(const Iterator& other); + bool operator!=(const Iterator& other) const; Iterator operator++(int); Iterator& operator++(); - bool operator==(const Iterator& other) { return current == other.current; } + bool operator==(const Iterator& other) const { return current == other.current; } }; Iterator begin() { return Iterator(_head); } Iterator end() { return Iterator(nullptr); } @@ -263,7 +263,7 @@ T& List::Iterator::operator*() { } template -bool List::Iterator::operator!=(const Iterator& other) { +bool List::Iterator::operator!=(const Iterator& other)const { return current != other.current; } diff --git a/tests/test_list.cpp b/tests/test_list.cpp index e290c067..6a309f7c 100644 --- a/tests/test_list.cpp +++ b/tests/test_list.cpp @@ -89,6 +89,56 @@ TEST(ListTest, DifferentTypes) { list.push_back("world"); EXPECT_EQ(list.size(), 2); } +TEST(ListTest, IteratorRead) { + List list; + for (int i = 0; i < 5; i++) { + list.push_back(i * 2); + } + std::vector result; + for (List::Iterator it = list.begin(); it != list.end(); it++) { + result.push_back(*it); + } + EXPECT_EQ(result.size(), 5u); + EXPECT_EQ(result[0], 0); + EXPECT_EQ(result[1], 2); + EXPECT_EQ(result[2], 4); + EXPECT_EQ(result[3], 6); + EXPECT_EQ(result[4], 8); +} + +TEST(ListTest, IteratorWrite) { + List list; + for (int i = 0; i < 5; i++) { + list.push_back(0); + } + int value = 1; + for (List::Iterator it = list.begin(); it != list.end(); ++it) { + *it = value * 10; + value++; + } + value = 1; + for (List::Iterator it = list.begin(); it != list.end(); ++it) { + EXPECT_EQ(*it, value * 10); + value++; + } +} + +TEST(ListTest, IteratorEmptyList) { + List list; + List::Iterator it1 = list.begin(); + EXPECT_EQ(it1, list.end()); + EXPECT_TRUE(list.begin() == list.end()); + int count = 0; + for (List::Iterator it = list.begin(); it != list.end(); it++) { + count++; + } + EXPECT_EQ(count, 0); + count = 0; + for (List::Iterator it = list.begin(); it != list.end(); ++it) { + count++; + } + EXPECT_EQ(count, 0); +} //TEST(ListTest, can_read) { // Listlist; // for (int i = 0; i < 10; i++) { From b9e779a9774c043cf2f203a9812edbe0307aa722 Mon Sep 17 00:00:00 2001 From: mrskristinaa Date: Tue, 2 Dec 2025 17:58:54 +0300 Subject: [PATCH 17/23] Doubly linked list with iterator --- CMakeLists.txt | 3 +- lib_doubly_linked_list/CMakeLists.txt | 1 + lib_doubly_linked_list/doubly_linked_list.cpp | 0 lib_doubly_linked_list/doubly_linked_list.h | 156 ++++++++++++++++++ tests/test_doubly_linked_list.cpp | 61 +++++++ 5 files changed, 220 insertions(+), 1 deletion(-) create mode 100644 lib_doubly_linked_list/CMakeLists.txt create mode 100644 lib_doubly_linked_list/doubly_linked_list.cpp create mode 100644 lib_doubly_linked_list/doubly_linked_list.h create mode 100644 tests/test_doubly_linked_list.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 292c7764..9de9527b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,8 @@ include(cmake/function.cmake) # подхватываем функции, add_subdirectory(lib_easy_example) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example add_subdirectory(lib_queue) -add_subdirectory(lib_list) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example +add_subdirectory(lib_list) +add_subdirectory(lib_doubly_linked_list) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example add_subdirectory(lib_stack) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example add_subdirectory(lib_dsu) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example add_subdirectory(lib_algorithms) diff --git a/lib_doubly_linked_list/CMakeLists.txt b/lib_doubly_linked_list/CMakeLists.txt new file mode 100644 index 00000000..f1314175 --- /dev/null +++ b/lib_doubly_linked_list/CMakeLists.txt @@ -0,0 +1 @@ +create_project_lib(DoublyLinkedList) \ No newline at end of file diff --git a/lib_doubly_linked_list/doubly_linked_list.cpp b/lib_doubly_linked_list/doubly_linked_list.cpp new file mode 100644 index 00000000..e69de29b diff --git a/lib_doubly_linked_list/doubly_linked_list.h b/lib_doubly_linked_list/doubly_linked_list.h new file mode 100644 index 00000000..fc161c55 --- /dev/null +++ b/lib_doubly_linked_list/doubly_linked_list.h @@ -0,0 +1,156 @@ +#pragma once +#include +template +struct DNode { + T value; + DNode* next; + DNode* prev; + DNode(T value_, DNode* prev_ = nullptr, DNode* next_ = nullptr) : value(value_), prev(prev_), next(next_) { + } +}; +template +class DoublyLinkedList { + DNode* _head; + DNode* _tail; + int _count; +public: + DoublyLinkedList() : _head(nullptr), _tail(nullptr), _count(0) {} + DoublyLinkedList(const DoublyLinkedList& other) : _head(nullptr), _tail(nullptr), _count(0) { + DNode* current = other._head; + while (current != nullptr) { + push_back(current->value); + current = current->next; + } + } + DoublyLinkedList& operator=(const DoublyLinkedList& other) { + if (this != &other) { + clear(); + DNode* current = other._head; + while (current != nullptr) { + push_back(current->value); + current = current->next; + } + } + return *this; + } + ~DoublyLinkedList() { + clear(); + } + void push_front(const T& val) noexcept { + DNode* node = new DNode(val, nullptr, _head); + if (_head != nullptr) { + _head->prev = node; + } + _head = node; + if (_tail == nullptr) { + _tail = node; + } + _count++; + } + void push_back(const T& val) noexcept { + DNode* node = new DNode(val, _tail, nullptr); + if (_tail != nullptr) { + _tail->next = node; + } + _tail = node; + if (_head == nullptr) { + _head = node; + } + _count++; + } + void pop_front() { + if (is_empty()) throw std::logic_error("Error: list is empty"); + DNode* temp = _head; + _head = _head->next; + if (_head != nullptr) { + _head->prev = nullptr; + } + else { + _tail = nullptr; + } + delete temp; + _count--; + } + void pop_back() { + if (is_empty()) throw std::logic_error("Error: list is empty"); + DNode* temp = _tail; + _tail = _tail->prev; + if (_tail != nullptr) { + _tail->next = nullptr; + } + else { + _head = nullptr; + } + delete temp; + _count--; + } + void clear() { + while (!is_empty()) { + pop_front(); + } + } + bool is_empty() const { + return _head == nullptr; + } + int size() const noexcept { + return _count; + } + class Iterator { + DNode* current; + public: + Iterator() : current(nullptr) {} + Iterator(DNode* pos) : current(pos) {} + Iterator(const Iterator& other) : current(other.current) {} + + Iterator& operator=(const Iterator& other) { + if (this != &other) { + current = other.current; + } + return *this; + } + T& operator*() { + if (current == nullptr) throw std::logic_error("Error: dereferencing null iterator"); + return current->value; + } + const T& operator*() const { + if (current == nullptr) throw std::logic_error("Error: dereferencing null iterator"); + return current->value; + } + bool operator!=(const Iterator& other) const { + return current != other.current; + } + bool operator==(const Iterator& other) const { + return current == other.current; + } + Iterator& operator++() { + if (current != nullptr) { + current = current->next; + } + return *this; + } + Iterator operator++(int) { + Iterator temp = *this; + if (current != nullptr) { + current = current->next; + } + return temp; + } + Iterator& operator--() { + if (current != nullptr) { + current = current->prev; + } + return *this; + } + Iterator operator--(int) { + Iterator temp = *this; + if (current != nullptr) { + current = current->prev; + } + return temp; + } + }; + Iterator begin() { return Iterator(_head); } + Iterator end() { return Iterator(nullptr); } + Iterator rbegin() { return Iterator(_tail); } + Iterator rend() { return Iterator(nullptr); } +}; \ No newline at end of file diff --git a/tests/test_doubly_linked_list.cpp b/tests/test_doubly_linked_list.cpp new file mode 100644 index 00000000..78d4fb60 --- /dev/null +++ b/tests/test_doubly_linked_list.cpp @@ -0,0 +1,61 @@ +#include +#include "doubly_linked_list.h" +TEST(DoublyLinkedListTest, IteratorEmpty) { + DoublyLinkedList list; + EXPECT_TRUE(list.begin() == list.end()); + EXPECT_EQ(list.size(), 0); + int count = 0; + for (auto it = list.begin(); it != list.end(); ++it) { + count++; + } + EXPECT_EQ(count, 0); + count = 0; + for (auto it = list.end(); it != list.begin(); --it) { + count++; + } + EXPECT_EQ(count, 0); +} +TEST(DoublyLinkedListTest, IteratorWrite) { + DoublyLinkedList list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + int value = 10; + for (auto it = list.begin(); it != list.end(); ++it) { + *it = value; + value += 10; + } + value = 10; + for (auto it = list.begin(); it != list.end(); ++it) { + EXPECT_EQ(*it, value); + value += 10; + } +} +TEST(DoublyLinkedListTest, IteratorReadAndBidirectional) { + DoublyLinkedList list; + + list.push_back(10); + list.push_back(20); + list.push_back(30); + + // + auto it = list.begin(); + EXPECT_EQ(*it, 10); + ++it; + EXPECT_EQ(*it, 20); + ++it; + EXPECT_EQ(*it, 30); + + // ( end()!) + auto it2 = list.begin(); + ++it2; // 20 + --it2; // 10 + EXPECT_EQ(*it2, 10); + + // + int sum = 0; + for (auto it = list.begin(); it != list.end(); ++it) { + sum += *it; + } + EXPECT_EQ(sum, 60); +} \ No newline at end of file From abdc2865f8443568a33f1b3819550d2482797808 Mon Sep 17 00:00:00 2001 From: mrskristinaa Date: Sun, 7 Dec 2025 18:10:40 +0300 Subject: [PATCH 18/23] corrected tests at DSU --- lib_dsu/dsu.h | 1 + tests/test_dsu.cpp | 88 ++++++++++++++-------------------------------- 2 files changed, 27 insertions(+), 62 deletions(-) diff --git a/lib_dsu/dsu.h b/lib_dsu/dsu.h index d11c5d13..23d3ee97 100644 --- a/lib_dsu/dsu.h +++ b/lib_dsu/dsu.h @@ -18,6 +18,7 @@ DSU::DSU(int size) : _size(size) { } DSU:: ~DSU() { delete[] _parent; + delete[] _rank; } int DSU::find(int x) { if (_parent[x] == x) { diff --git a/tests/test_dsu.cpp b/tests/test_dsu.cpp index d95d7945..0ee2732a 100644 --- a/tests/test_dsu.cpp +++ b/tests/test_dsu.cpp @@ -1,83 +1,47 @@ #include #include "dsu.h" -TEST(DSUBasicTest, Initialization) { +TEST(DSUTest, InitialState) { DSU dsu(5); - EXPECT_EQ(dsu.find(0), 0); - EXPECT_EQ(dsu.find(1), 1); - EXPECT_EQ(dsu.find(2), 2); - EXPECT_EQ(dsu.find(3), 3); - EXPECT_EQ(dsu.find(4), 4); + for (int i = 0; i < 5; i++) { + EXPECT_EQ(dsu.find(i), i); + } } - -TEST(DSUBasicTest, SimpleUnion) { +TEST(DSUTest, SimpleUnion) { DSU dsu(3); dsu.unite(0, 1); - int root0 = dsu.find(0); - int root1 = dsu.find(1); - int root2 = dsu.find(2); - EXPECT_EQ(root0, root1); - EXPECT_NE(root0, root2); -} - -TEST(DSUBasicTest, MultipleUnions) { - DSU dsu(5); - dsu.unite(0, 1); - dsu.unite(2, 3); EXPECT_EQ(dsu.find(0), dsu.find(1)); - EXPECT_EQ(dsu.find(2), dsu.find(3)); EXPECT_NE(dsu.find(0), dsu.find(2)); - EXPECT_NE(dsu.find(1), dsu.find(4)); } - -TEST(DSUBasicTest, TransitiveConnection) { +TEST(DSUTest, TransitiveUnion) { DSU dsu(4); dsu.unite(0, 1); dsu.unite(1, 2); - dsu.unite(2, 3); - EXPECT_EQ(dsu.find(0), dsu.find(3)); - EXPECT_EQ(dsu.find(1), dsu.find(3)); -} - -TEST(DSUBasicTest, RankBehavior) { - DSU dsu(4); - dsu.unite(0, 1); - dsu.unite(2, 3); - int root1 = dsu.find(0); - int root2 = dsu.find(2); - dsu.unite(0, 2); - EXPECT_EQ(dsu.find(0), dsu.find(1)); EXPECT_EQ(dsu.find(0), dsu.find(2)); - EXPECT_EQ(dsu.find(0), dsu.find(3)); -} - -TEST(DSUBasicTest, SelfUnion) { - DSU dsu(3); - dsu.unite(1, 1); - EXPECT_EQ(dsu.find(1), 1); + EXPECT_NE(dsu.find(0), dsu.find(3)); } - -TEST(DSUBasicTest, ChainUnion) { +TEST(DSUTest, MultipleUnions) { DSU dsu(6); dsu.unite(0, 1); - dsu.unite(1, 2); dsu.unite(2, 3); - dsu.unite(3, 4); - EXPECT_EQ(dsu.find(0), dsu.find(4)); - EXPECT_NE(dsu.find(0), dsu.find(5)); + dsu.unite(4, 5); + EXPECT_EQ(dsu.find(0), dsu.find(1)); + EXPECT_EQ(dsu.find(2), dsu.find(3)); + EXPECT_EQ(dsu.find(4), dsu.find(5)); + EXPECT_NE(dsu.find(0), dsu.find(2)); + EXPECT_NE(dsu.find(0), dsu.find(4)); + EXPECT_NE(dsu.find(2), dsu.find(4)); } - -TEST(DSUMemoryTest, LargeDSU) { - const int SIZE = 1000; - DSU dsu(SIZE); - for (int i = 2; i < SIZE; i += 2) { - dsu.unite(0, i); +TEST(DSUTest, UnionAllElements) { + DSU dsu(5); + for (int i = 0; i < 4; i++) { + dsu.unite(i, i + 1); } - for (int i = 3; i < SIZE; i += 2) { - dsu.unite(1, i); + for (int i = 1; i < 5; i++) { + EXPECT_EQ(dsu.find(0), dsu.find(i)); } - EXPECT_EQ(dsu.find(0), dsu.find(2)); - EXPECT_EQ(dsu.find(0), dsu.find(4)); - EXPECT_EQ(dsu.find(1), dsu.find(3)); - EXPECT_EQ(dsu.find(1), dsu.find(5)); - EXPECT_NE(dsu.find(0), dsu.find(1)); +} +TEST(DSUTest, SelfUnion) { + DSU dsu(3); + dsu.unite(0, 0); + EXPECT_EQ(dsu.find(0), 0); } \ No newline at end of file From 4eab9fa54aa60507911db4d9ba1fca158c822e87 Mon Sep 17 00:00:00 2001 From: mrskristinaa Date: Mon, 8 Dec 2025 13:20:28 +0300 Subject: [PATCH 19/23] Delete lib_stack directory --- lib_stack/CMakeLists.txt | 1 - lib_stack/stack.cpp | 0 lib_stack/stack.h | 95 ---------------------------------------- 3 files changed, 96 deletions(-) delete mode 100644 lib_stack/CMakeLists.txt delete mode 100644 lib_stack/stack.cpp delete mode 100644 lib_stack/stack.h diff --git a/lib_stack/CMakeLists.txt b/lib_stack/CMakeLists.txt deleted file mode 100644 index 77959ec8..00000000 --- a/lib_stack/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -create_project_lib(Stack) diff --git a/lib_stack/stack.cpp b/lib_stack/stack.cpp deleted file mode 100644 index e69de29b..00000000 diff --git a/lib_stack/stack.h b/lib_stack/stack.h deleted file mode 100644 index ed44771b..00000000 --- a/lib_stack/stack.h +++ /dev/null @@ -1,95 +0,0 @@ -#pragma once -#ifndef STACK_H -#define STACK_H -#include -template -class Stack { -private: - T* _data; - int _size; - int _top; - -public: - explicit Stack(int size = 100); - Stack(const Stack& other); - ~Stack(); - Stack& operator=(const Stack& other); - void push(const T& val); - void pop(); - inline T top() const; - inline bool is_empty() const noexcept; - inline bool is_full() const noexcept; - void clear() noexcept; -}; - -template -Stack::Stack(int size) : _size(size), _top(-1) { - if (size <= 0) { - throw std::invalid_argument("Stack size must be positive"); - } - _data = new T[_size]; -} -template -Stack::Stack(const Stack& other) : _size(other._size), _top(other._top) { - _data = new T[_size]; - for (int i = 0; i <= _top; i++) { - _data[i] = other._data[i]; - } -} -template -Stack::~Stack() { - delete[] _data; -} -template -Stack& Stack::operator=(const Stack& other) { - if (this != &other) { - delete[] _data; - _size = other._size; - _top = other._top; - _data = new T[_size]; - for (int i = 0; i <= _top; i++) { - _data[i] = other._data[i]; - } - } - return *this; -} -template -void Stack::push(const T& val) { - if (is_full()) { - throw std::logic_error("Stack is full"); - } - _data[++_top] = val; -} - -template -void Stack::pop() { - if (is_empty()) { - throw std::logic_error("Stack is empty"); - } - --_top; -} - -template -T Stack::top() const { - if (is_empty()) { - throw std::logic_error("Stack is empty"); - } - return _data[_top]; -} - -template -bool Stack::is_empty() const noexcept { - return _top == -1; -} - -template -bool Stack::is_full() const noexcept { - return _top == _size - 1; -} - -template -void Stack::clear() noexcept { - _top = -1; -} - -#endif // STACK_H \ No newline at end of file From 251032302a06b50624fe0d0a9069be7b34f4665e Mon Sep 17 00:00:00 2001 From: mrskristinaa Date: Mon, 8 Dec 2025 13:21:50 +0300 Subject: [PATCH 20/23] Delete lib_queue directory --- lib_queue/CMakeLists.txt | 1 - lib_queue/queue.cpp | 0 lib_queue/queue.h | 125 --------------------------------------- 3 files changed, 126 deletions(-) delete mode 100644 lib_queue/CMakeLists.txt delete mode 100644 lib_queue/queue.cpp delete mode 100644 lib_queue/queue.h diff --git a/lib_queue/CMakeLists.txt b/lib_queue/CMakeLists.txt deleted file mode 100644 index f0846b24..00000000 --- a/lib_queue/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -create_project_lib(Queue) \ No newline at end of file diff --git a/lib_queue/queue.cpp b/lib_queue/queue.cpp deleted file mode 100644 index e69de29b..00000000 diff --git a/lib_queue/queue.h b/lib_queue/queue.h deleted file mode 100644 index 8324a5a9..00000000 --- a/lib_queue/queue.h +++ /dev/null @@ -1,125 +0,0 @@ -#pragma once -#ifndef QUEUE_H -#define QUEUE_H -#include - -template -class Queue { -private: - T* _data; - int _size; - int _head; - int _count; -public: - explicit Queue(int size = 100); - Queue(const Queue& other); - Queue& operator=(const Queue& other); - ~Queue(); - void enqueue(const T& val); - void dequeue(); - inline T front() const; - inline T back() const; - inline bool is_empty() const noexcept; - inline bool is_full() const noexcept; - inline int size() const noexcept; - void clear() noexcept; -}; - -template -Queue::Queue(int size) : _size(size), _head(0), _count(0) { - if (size <= 0) { - throw std::invalid_argument("Queue size must be positive"); - } - _data = new T[_size]; -} - -template -Queue::Queue(const Queue& other) : _size(other._size), _head(other._head), _count(other._count) { - _data = new T[_size]; - for (int i = 0; i < _count; i++) { - int index = (other._head + i) % other._size; - _data[index] = other._data[index]; - } -} - -template -Queue& Queue::operator=(const Queue& other) { - if (this != &other) { - delete[] _data; - - _size = other._size; - _head = other._head; - _count = other._count; - - _data = new T[_size]; - for (int i = 0; i < _count; i++) { - int index = (other._head + i) % other._size; - _data[index] = other._data[index]; - } - } - return *this; -} - -template -Queue::~Queue() { - delete[] _data; -} - -template -void Queue::enqueue(const T& val) { - if (is_full()) { - throw std::logic_error("Queue is full"); - } - int tail = (_head + _count) % _size; - _data[tail] = val; - _count++; -} - -template -void Queue::dequeue() { - if (is_empty()) { - throw std::logic_error("Queue is empty"); - } - _head = (_head + 1) % _size; - _count--; -} - -template -T Queue::front() const { - if (is_empty()) { - throw std::logic_error("Queue is empty"); - } - return _data[_head]; -} - -template -T Queue::back() const { - if (is_empty()) { - throw std::logic_error("Queue is empty"); - } - int tail = (_head + _count - 1) % _size; - return _data[tail]; -} - -template -bool Queue::is_empty() const noexcept { - return _count == 0; -} - -template -bool Queue::is_full() const noexcept { - return _count == _size; -} - -template -int Queue::size() const noexcept { - return _count; -} - -template -void Queue::clear() noexcept { - _head = 0; - _count = 0; -} - -#endif // QUEUE_H \ No newline at end of file From 30aa2aa20c466f0c1b25b45c159aede3afef5726 Mon Sep 17 00:00:00 2001 From: mrskristinaa Date: Mon, 8 Dec 2025 13:22:09 +0300 Subject: [PATCH 21/23] Delete lib_doubly_linked_list directory --- lib_doubly_linked_list/CMakeLists.txt | 1 - lib_doubly_linked_list/doubly_linked_list.cpp | 0 lib_doubly_linked_list/doubly_linked_list.h | 156 ------------------ 3 files changed, 157 deletions(-) delete mode 100644 lib_doubly_linked_list/CMakeLists.txt delete mode 100644 lib_doubly_linked_list/doubly_linked_list.cpp delete mode 100644 lib_doubly_linked_list/doubly_linked_list.h diff --git a/lib_doubly_linked_list/CMakeLists.txt b/lib_doubly_linked_list/CMakeLists.txt deleted file mode 100644 index f1314175..00000000 --- a/lib_doubly_linked_list/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -create_project_lib(DoublyLinkedList) \ No newline at end of file diff --git a/lib_doubly_linked_list/doubly_linked_list.cpp b/lib_doubly_linked_list/doubly_linked_list.cpp deleted file mode 100644 index e69de29b..00000000 diff --git a/lib_doubly_linked_list/doubly_linked_list.h b/lib_doubly_linked_list/doubly_linked_list.h deleted file mode 100644 index fc161c55..00000000 --- a/lib_doubly_linked_list/doubly_linked_list.h +++ /dev/null @@ -1,156 +0,0 @@ -#pragma once -#include -template -struct DNode { - T value; - DNode* next; - DNode* prev; - DNode(T value_, DNode* prev_ = nullptr, DNode* next_ = nullptr) : value(value_), prev(prev_), next(next_) { - } -}; -template -class DoublyLinkedList { - DNode* _head; - DNode* _tail; - int _count; -public: - DoublyLinkedList() : _head(nullptr), _tail(nullptr), _count(0) {} - DoublyLinkedList(const DoublyLinkedList& other) : _head(nullptr), _tail(nullptr), _count(0) { - DNode* current = other._head; - while (current != nullptr) { - push_back(current->value); - current = current->next; - } - } - DoublyLinkedList& operator=(const DoublyLinkedList& other) { - if (this != &other) { - clear(); - DNode* current = other._head; - while (current != nullptr) { - push_back(current->value); - current = current->next; - } - } - return *this; - } - ~DoublyLinkedList() { - clear(); - } - void push_front(const T& val) noexcept { - DNode* node = new DNode(val, nullptr, _head); - if (_head != nullptr) { - _head->prev = node; - } - _head = node; - if (_tail == nullptr) { - _tail = node; - } - _count++; - } - void push_back(const T& val) noexcept { - DNode* node = new DNode(val, _tail, nullptr); - if (_tail != nullptr) { - _tail->next = node; - } - _tail = node; - if (_head == nullptr) { - _head = node; - } - _count++; - } - void pop_front() { - if (is_empty()) throw std::logic_error("Error: list is empty"); - DNode* temp = _head; - _head = _head->next; - if (_head != nullptr) { - _head->prev = nullptr; - } - else { - _tail = nullptr; - } - delete temp; - _count--; - } - void pop_back() { - if (is_empty()) throw std::logic_error("Error: list is empty"); - DNode* temp = _tail; - _tail = _tail->prev; - if (_tail != nullptr) { - _tail->next = nullptr; - } - else { - _head = nullptr; - } - delete temp; - _count--; - } - void clear() { - while (!is_empty()) { - pop_front(); - } - } - bool is_empty() const { - return _head == nullptr; - } - int size() const noexcept { - return _count; - } - class Iterator { - DNode* current; - public: - Iterator() : current(nullptr) {} - Iterator(DNode* pos) : current(pos) {} - Iterator(const Iterator& other) : current(other.current) {} - - Iterator& operator=(const Iterator& other) { - if (this != &other) { - current = other.current; - } - return *this; - } - T& operator*() { - if (current == nullptr) throw std::logic_error("Error: dereferencing null iterator"); - return current->value; - } - const T& operator*() const { - if (current == nullptr) throw std::logic_error("Error: dereferencing null iterator"); - return current->value; - } - bool operator!=(const Iterator& other) const { - return current != other.current; - } - bool operator==(const Iterator& other) const { - return current == other.current; - } - Iterator& operator++() { - if (current != nullptr) { - current = current->next; - } - return *this; - } - Iterator operator++(int) { - Iterator temp = *this; - if (current != nullptr) { - current = current->next; - } - return temp; - } - Iterator& operator--() { - if (current != nullptr) { - current = current->prev; - } - return *this; - } - Iterator operator--(int) { - Iterator temp = *this; - if (current != nullptr) { - current = current->prev; - } - return temp; - } - }; - Iterator begin() { return Iterator(_head); } - Iterator end() { return Iterator(nullptr); } - Iterator rbegin() { return Iterator(_tail); } - Iterator rend() { return Iterator(nullptr); } -}; \ No newline at end of file From 4222e5a6fef20b02c92ee7f851138738022bc864 Mon Sep 17 00:00:00 2001 From: mrskristinaa Date: Mon, 8 Dec 2025 13:22:26 +0300 Subject: [PATCH 22/23] Delete lib_list directory --- lib_list/CMakeLists.txt | 1 - lib_list/list.cpp | 0 lib_list/list.h | 283 ---------------------------------------- lib_list/stack.h | 82 ------------ 4 files changed, 366 deletions(-) delete mode 100644 lib_list/CMakeLists.txt delete mode 100644 lib_list/list.cpp delete mode 100644 lib_list/list.h delete mode 100644 lib_list/stack.h diff --git a/lib_list/CMakeLists.txt b/lib_list/CMakeLists.txt deleted file mode 100644 index 148b539a..00000000 --- a/lib_list/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -create_project_lib(List) \ No newline at end of file diff --git a/lib_list/list.cpp b/lib_list/list.cpp deleted file mode 100644 index e69de29b..00000000 diff --git a/lib_list/list.h b/lib_list/list.h deleted file mode 100644 index 51eed6cd..00000000 --- a/lib_list/list.h +++ /dev/null @@ -1,283 +0,0 @@ -#pragma once -#include -template -struct Node { - T value; - Node* next; - Node(T value_, Node* next_ = nullptr); -}; -template -class List { - Node* _head, * _tail; - int _count; -public: - List() :_head(nullptr), _tail(nullptr), _count(0) {} - List(const List& other); - List& operator=(const List& other); - ~List(); - - void push_front(const T& val) noexcept; - void push_back(const T& val) noexcept; - void insert(int pos, const T& val); - void insert(Node* node, const T& val); - - void pop_front(); - void pop_back(); - void erase(int pos); - void erase(Node* node); - void clear(); - - bool is_empty() const; - int size() const noexcept; - Node* find(const T& val); - class Iterator { - Node* current; - public: - Iterator() : current(nullptr) {} - Iterator(Node* pos) : current(pos) {} - Iterator(const Iterator& other) : current(other.current) {} - - Iterator& operator=(const Iterator& other); - T& operator*(); - bool operator!=(const Iterator& other) const; - Iterator operator++(int); - Iterator& operator++(); - bool operator==(const Iterator& other) const { return current == other.current; } - }; - Iterator begin() { return Iterator(_head); } - Iterator end() { return Iterator(nullptr); } -}; - -template -Node::Node(T value_, Node* next_) : value(value_), next(next_) {} - -template -List::List(const List& other) : _head(nullptr), _tail(nullptr), _count(0) { - Node* current = other._head; - while (current != nullptr) { - push_back(current->value); - current = current->next; - } -} -template -List& List::operator=(const List& other) { - if (this != &other) { - clear(); - Node* current = other._head; - while (current != nullptr) { - push_back(current->value); - current = current->next; - } - } - return *this; -} -template -List::~List() { - clear(); -} - -template -void List::push_front(const T& val) noexcept { - Node* node = new Node(val, _head); - if (is_empty()) _tail = node; - _head = node; - _count++; -} - -template -void List::push_back(const T& val) noexcept { - Node* node = new Node(val); - if (is_empty()) { - _head = node; - _tail = node; - _count++; - return; - } - _tail->next = node; - _tail = node; - ++_count; -} - -template -void List::insert(Node* node, const T& val) { - if (node == nullptr) throw std::logic_error ("Error: null node"); - Node* new_node = new Node(val, node->next); - node->next = new_node; - if (_tail == node) { - _tail = new_node; - } - _count++; -} - -template -void List::insert(int pos, const T& val) { - if (pos < 0 || pos > _count) throw std::logic_error ("Error: position out of range"); - - if (pos == 0) { - push_front(val); - return; - } - else if (pos == _count) { - push_back(val); - return; - } - - int cur_pos = 0; - Node* cur = _head; - while (cur != nullptr) { - if (cur_pos == pos - 1) break; - cur_pos++; - cur = cur->next; - } - insert(cur, val); -} - -template -void List::pop_front() { - if (is_empty()) throw std::logic_error ("Error: list is empty"); - - Node* temp = _head; - _head = _head->next; - delete temp; - _count--; - - if (_head == nullptr) { - _tail = nullptr; - } -} - -template -void List::pop_back() { - if (is_empty()) throw std::logic_error ("Error: list is empty"); - - if (_head == _tail) { - delete _head; - _head = _tail = nullptr; - _count = 0; - return; - } - - Node* current = _head; - while (current->next != _tail) { - current = current->next; - } - - delete _tail; - _tail = current; - _tail->next = nullptr; - _count--; -} - -template -void List::erase(Node* node) { - if (node == nullptr || is_empty()) throw std::logic_error ("Error: invalid node or empty list"); - - if (node == _head) { - pop_front(); - return; - } - - Node* prev = _head; - while (prev != nullptr && prev->next != node) { - prev = prev->next; - } - - if (prev == nullptr) throw std::logic_error ("Error: node not found in list"); - - prev->next = node->next; - if (node == _tail) { - _tail = prev; - } - - delete node; - _count--; -} - -template -void List::erase(int pos) { - if (pos < 0 || pos >= _count) throw std::logic_error ("Error: position out of range"); - - if (pos == 0) { - pop_front(); - return; - } - - int cur_pos = 0; - Node* cur = _head; - while (cur_pos < pos - 1) { - cur_pos++; - cur = cur->next; - } - - Node* toDelete = cur->next; - cur->next = toDelete->next; - - if (toDelete == _tail) { - _tail = cur; - } - - delete toDelete; - _count--; -} - -template -void List::clear() { - while (!is_empty()) { - pop_front(); - } -} - -template -bool List::is_empty() const { - return _head == nullptr; -} -template -int List::size() const noexcept { - return _count; -} -template -Node* List::find(const T& val) { - Node* current = _head; - while (current != nullptr) { - if (current->value == val) { - return current; - } - current = current->next; - } - return nullptr; -} - - -template -typename List::Iterator& List::Iterator::operator=(const Iterator& other) { - if (this != &other) { - current = other.current; - } - return *this; -} - -template -T& List::Iterator::operator*() { - if (current == nullptr) throw std::logic_error ("Error: dereferencing null iterator"); - return current->value; -} - -template -bool List::Iterator::operator!=(const Iterator& other)const { - return current != other.current; -} - -template -typename List::Iterator List::Iterator::operator++(int) { - if (current == nullptr) throw std::logic_error ("Error: incrementing null iterator"); - Iterator temp = *this; - current = current->next; - return temp; -} - -template -typename List::Iterator& List::Iterator::operator++() { - if (current == nullptr) throw std::logic_error ("Error: incrementing null iterator"); - current = current->next; - return *this; -} \ No newline at end of file diff --git a/lib_list/stack.h b/lib_list/stack.h deleted file mode 100644 index ed33a054..00000000 --- a/lib_list/stack.h +++ /dev/null @@ -1,82 +0,0 @@ -#pragma once -#include "list.h" -#include -#ifndef STACK_LIST_H -#define STACK_LIST_H -template -class StackList { -private: - List* _list; -public: - StackList() { - _list = new List(); - } - StackList(const StackList& other) { - _list = new List(*other._list); - } - - - ~StackList() { - delete _list; - _list = nullptr; - } - - - StackList& operator=(const StackList& other) { - if (this != &other) { - delete _list; - _list = new List(*other._list); - } - return *this; - } - - void push(const T& val); - void pop(); - T top() const; - bool is_empty() const noexcept; - void clear() noexcept; - int size() const noexcept; -}; - -template -void StackList::push(const T& val) { - _list->push_front(val); -} - -template -void StackList::pop() { - if (is_empty()) { - throw std::logic_error("Stack is empty"); - } - _list->pop_front(); -} - -template -T StackList::top() const { - if (is_empty()) { - throw std::logic_error("Stack is empty"); - } - auto it = _list->begin(); - return *it; -} - -template -bool StackList::is_empty() const noexcept { - return _list->is_empty(); -} - -template -void StackList::clear() noexcept { - _list->clear(); -} - -template -int StackList::size() const noexcept { - int count = 0; - for (auto it = _list->begin(); it != _list->end(); ++it) { - count++; - } - return count; -} - -#endif // STACK_LIST_H \ No newline at end of file From bed8b20b5887b73dce2638eb5f0b910354ca4d44 Mon Sep 17 00:00:00 2001 From: mrskristinaa Date: Mon, 8 Dec 2025 13:23:04 +0300 Subject: [PATCH 23/23] Delete lib_algorithms directory --- lib_algorithms/CMakeLists.txt | 2 -- lib_algorithms/algorithms.cpp | 21 --------------------- lib_algorithms/algorithms.h | 5 ----- 3 files changed, 28 deletions(-) delete mode 100644 lib_algorithms/CMakeLists.txt delete mode 100644 lib_algorithms/algorithms.cpp delete mode 100644 lib_algorithms/algorithms.h diff --git a/lib_algorithms/CMakeLists.txt b/lib_algorithms/CMakeLists.txt deleted file mode 100644 index cbdb9b66..00000000 --- a/lib_algorithms/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -create_project_lib(Algorithms) -add_depend(Algorithms Stack ..\\lib_stack) diff --git a/lib_algorithms/algorithms.cpp b/lib_algorithms/algorithms.cpp deleted file mode 100644 index e41593a9..00000000 --- a/lib_algorithms/algorithms.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "algorithms.h" -#include "stack.h" -bool check_algorithms(const std::string& symbol) { - Stack stack; - for (char ch : symbol) { - if (ch == '(' || ch == '{' || ch == '[') { - stack.push(ch); - } - else if (ch == ')' || ch == '}' || ch == ']') { - if (stack.is_empty()) { - return false; - } - char top_char = stack.top(); - stack.pop(); - if ((ch == ')' && top_char != '(') || (ch == '}' && top_char != '{') || (ch == ']' && top_char != '[')) { - return false; - } - } - } - return stack.is_empty(); -} \ No newline at end of file diff --git a/lib_algorithms/algorithms.h b/lib_algorithms/algorithms.h deleted file mode 100644 index 0003135c..00000000 --- a/lib_algorithms/algorithms.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef ALGORITHMS_H -#define ALGORITHMS_H -#include -bool check_algorithms(const std::string& symbol); -#endif // ALGORITHMS_H \ No newline at end of file