diff --git a/lib/src/util.cpp b/lib/src/util.cpp index 81e15bd5..9db3d1a9 100644 --- a/lib/src/util.cpp +++ b/lib/src/util.cpp @@ -1 +1,2 @@ #include "util.hpp" + diff --git a/lib/src/util.hpp b/lib/src/util.hpp index e69de29b..6d9f986f 100644 --- a/lib/src/util.hpp +++ b/lib/src/util.hpp @@ -0,0 +1,17 @@ +#include +#pragma once + +template +int Partition(std::vector& v, int low, int high) { + int pivot = v[high]; + int i = low - 1; + + for (int j = low; j <= high - 1; j++) { + if (v[j] <= pivot) { + i++; + std::swap(v[i], v[j]); + } + } + std::swap(v[i + 1], v[high]); + return (i + 1); +} \ No newline at end of file diff --git a/task_01/src/main.cpp b/task_01/src/main.cpp index 0e4393ba..43690ca5 100644 --- a/task_01/src/main.cpp +++ b/task_01/src/main.cpp @@ -1,3 +1,22 @@ #include +#include -int main() { return 0; } +#include "utils.hpp" + +int main() { + int size; + std::cin >> size; + std::vector v(size); + for (int i = 0; i < v.size(); i++) { + std::cin >> v[i]; + } + int targetSum; + std::cin >> targetSum; + std::pair ans = FindTargetSumInArray(v, targetSum); + if (ans.first != -1) + std::cout << ans.first << " " << ans.second; + else + std::cout << "Not found"; + + return 0; +} diff --git a/task_01/src/test.cpp b/task_01/src/test.cpp index ef5a86ae..985460eb 100644 --- a/task_01/src/test.cpp +++ b/task_01/src/test.cpp @@ -1,8 +1,33 @@ #include -#include "topology_sort.hpp" +#include +#include + +#include "utils.hpp" TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] -} + std::vector v1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + ASSERT_EQ(FindTargetSumInArray(v1, 0), std::make_pair(-1, -1)); + ASSERT_EQ(FindTargetSumInArray(v1, 1), std::make_pair(0, 1)); + ASSERT_EQ(FindTargetSumInArray(v1, 9), std::make_pair(0, 9)); + ASSERT_EQ(FindTargetSumInArray(v1, 11), std::make_pair(1, 10)); + ASSERT_EQ(FindTargetSumInArray(v1, -5), std::make_pair(-1, -1)); + + std::vector v2{0}; + ASSERT_EQ(FindTargetSumInArray(v2, 0), std::make_pair(-1, -1)); + ASSERT_EQ(FindTargetSumInArray(v2, 47), std::make_pair(-1, -1)); + ASSERT_EQ(FindTargetSumInArray(v2, -47), std::make_pair(-1, -1)); + + std::vector v3{-11, -6, 0, 1, 2, 4, 10, 16}; + ASSERT_EQ(FindTargetSumInArray(v3, -6), std::make_pair(1, 2)); + ASSERT_EQ(FindTargetSumInArray(v3, -7), std::make_pair(0, 5)); + ASSERT_EQ(FindTargetSumInArray(v3, -8), std::make_pair(-1, -1)); + ASSERT_EQ(FindTargetSumInArray(v3, 5), std::make_pair(0, 7)); + ASSERT_EQ(FindTargetSumInArray(v3, 4), std::make_pair(1, 6)); + ASSERT_EQ(FindTargetSumInArray(v3, 10), std::make_pair(1, 7)); + ASSERT_EQ(FindTargetSumInArray(v3, -60), std::make_pair(-1, -1)); + ASSERT_EQ(FindTargetSumInArray(v3, -12), std::make_pair(-1, -1)); + ASSERT_EQ(FindTargetSumInArray(v3, 47), std::make_pair(-1, -1)); + ASSERT_EQ(FindTargetSumInArray(v3, 11), std::make_pair(3, 6)); +} \ No newline at end of file diff --git a/task_01/src/topology_sort.cpp b/task_01/src/topology_sort.cpp deleted file mode 100644 index e53f670c..00000000 --- a/task_01/src/topology_sort.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "topology_sort.hpp" diff --git a/task_01/src/topology_sort.hpp b/task_01/src/topology_sort.hpp deleted file mode 100644 index 6f70f09b..00000000 --- a/task_01/src/topology_sort.hpp +++ /dev/null @@ -1 +0,0 @@ -#pragma once diff --git a/task_01/src/utils.cpp b/task_01/src/utils.cpp new file mode 100644 index 00000000..0f1278f6 --- /dev/null +++ b/task_01/src/utils.cpp @@ -0,0 +1,14 @@ +#include "utils.hpp" + +std::pair FindTargetSumInArray(std::vector v, int targetSum) { + int i = 0, j = v.size() - 1; + while (v[i] < v[j]) { + if (v[i] + v[j] > targetSum) + j--; + else if (v[i] + v[j] < targetSum) + i++; + else + return std::pair(i, j); + } + return std::pair(-1, -1); +} \ No newline at end of file diff --git a/task_01/src/utils.hpp b/task_01/src/utils.hpp new file mode 100644 index 00000000..894134ef --- /dev/null +++ b/task_01/src/utils.hpp @@ -0,0 +1,8 @@ +#pragma once +#include +#include +// Returns pair of indices, which gives in sum target sum +// If target sun is not presented returns pair -1; -1 +// If we target sum presented in several ways returns i, j +// So that i is minimumal index and j is maximum index +std::pair FindTargetSumInArray(std::vector v, int targetSum); \ No newline at end of file diff --git a/task_02/src/main.cpp b/task_02/src/main.cpp index 0e4393ba..0db7939b 100644 --- a/task_02/src/main.cpp +++ b/task_02/src/main.cpp @@ -1,3 +1,7 @@ #include +#include "stack.hpp" + +using namespace std; + int main() { return 0; } diff --git a/task_02/src/stack.cpp b/task_02/src/stack.cpp deleted file mode 100644 index 8ca89902..00000000 --- a/task_02/src/stack.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "stack.hpp" - -#include - -void Stack::Push(int value) { data_.push(value); } - -int Stack::Pop() { - auto result = data_.top(); - data_.pop(); - return result; -} - -void MinStack::Push(int value) { data_.push_back(value); } - -int MinStack::Pop() { - auto result = data_.back(); - data_.pop_back(); - return result; -} - -int MinStack::GetMin() { return *std::min_element(data_.begin(), data_.end()); } \ No newline at end of file diff --git a/task_02/src/stack.hpp b/task_02/src/stack.hpp index 138ec40f..17b35736 100644 --- a/task_02/src/stack.hpp +++ b/task_02/src/stack.hpp @@ -1,23 +1,103 @@ #pragma once +#include +#include #include +#include +#include #include +template +class StackNode { + public: + explicit StackNode(T _data, StackNode *_prev = nullptr) + : data(_data), prev_ptr(_prev) {} + StackNode() : data(), prev_ptr(nullptr) {} + T data; + StackNode *prev_ptr; +}; + +template class Stack { public: - void Push(int value); - int Pop(); + Stack() : top_(nullptr), size_(0) {} + void Push(T value); + T Pop(); + T GetTop(); + int GetSize(); private: - std::stack data_; + StackNode *top_; + int size_; }; +template +void Stack::Push(T value) { + StackNode *new_elem = new StackNode(value, top_); + size_++; + top_ = new_elem; +} + +template +T Stack::Pop() { + if (size_ == 0) { + throw std::underflow_error("Empty stack"); + } + T returning_value = std::move(top_->data); + StackNode *old_top = top_; + top_ = top_->prev_ptr; + delete old_top; + size_--; + return returning_value; +} + +template +int Stack::GetSize() { + return size_; +} + +template +T Stack::GetTop() { + if (size_ == 0) { + throw std::underflow_error("Empty stack"); + } + return top_->data; +} +template class MinStack { public: - void Push(int value); - int Pop(); - int GetMin(); + MinStack() : main_stack_(), min_stack_() {} + void Push(T value); + T Pop(); + T GetMin(); + int GetSize(); private: - std::vector data_; + Stack main_stack_; + Stack min_stack_; }; + +template +void MinStack::Push(T value) { + main_stack_.Push(value); + if (min_stack_.GetSize() == 0) + min_stack_.Push(value); + else + min_stack_.Push(std::min(value, min_stack_.GetTop())); +} + +template +T MinStack::Pop() { + min_stack_.Pop(); + return main_stack_.Pop(); +} + +template +T MinStack::GetMin() { + return min_stack_.GetTop(); +} + +template +int MinStack::GetSize() { + return main_stack_.GetSize(); +} diff --git a/task_02/src/test.cpp b/task_02/src/test.cpp index 54e7ce90..9960b93c 100644 --- a/task_02/src/test.cpp +++ b/task_02/src/test.cpp @@ -6,7 +6,7 @@ #include "stack.hpp" TEST(StackTest, Simple) { - Stack stack; + Stack stack; stack.Push(1); // Stack [1] ASSERT_EQ(stack.Pop(), 1); // Stack [] stack.Push(1); // Stack [1] @@ -22,7 +22,7 @@ TEST(StackTest, Simple) { } TEST(MinStackTest, Simple) { - MinStack stack; + MinStack stack; stack.Push(1); // Stack [1] ASSERT_EQ(stack.GetMin(), 1); ASSERT_EQ(stack.Pop(), 1); // Stack [] diff --git a/task_03/README.md b/task_03/README.md index 0819a478..9dad9b69 100644 --- a/task_03/README.md +++ b/task_03/README.md @@ -1,3 +1,4 @@ # Задача на количество дней перед потеплением -Написать функцию в которую передается темепература за каждый день в определенный момент день, нужно вернуть количество дней до повышения температуры для каждого дня, если температура не повысится, то для этого дня поставить в результирующий массив 0. +Написать функцию в которую передается темепература за каждый день в определенный момент дня. Вернуть количество дней до повышения температуры для каждого дня. Если температура не повысится, для этого дня поставить в результирующий массив 0. + diff --git a/task_03/src/main.cpp b/task_03/src/main.cpp index 0e4393ba..94c5405d 100644 --- a/task_03/src/main.cpp +++ b/task_03/src/main.cpp @@ -1,3 +1,4 @@ #include +#include "weather_report.h" int main() { return 0; } diff --git a/task_03/src/test.cpp b/task_03/src/test.cpp index ef5a86ae..f91b0537 100644 --- a/task_03/src/test.cpp +++ b/task_03/src/test.cpp @@ -1,8 +1,17 @@ #include -#include "topology_sort.hpp" +#include "weather_report.h" -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] -} +TEST(findNextGreater, Simple) { + ASSERT_EQ(FindNextGreater(std::vector{1}), (std::vector{-1})); + ASSERT_EQ(FindNextGreater(std::vector{}), (std::vector{})); + ASSERT_EQ(FindNextGreater(std::vector{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}), + (std::vector{1, 1, 1, 1, 1, 1, 1, 1, 1, -1})); + ASSERT_EQ( + FindNextGreater(std::vector{16, 19, 10, 14, 22, 27, 12, 10, 16, 24}), + (std::vector{{1, 3, 1, 1, 1, -1, 2, 1, 1, -1}})); + ASSERT_EQ(FindNextGreater( + std::vector{-29, 0, -7, -14, 0, -11, -13, -3, -27, -25}), + (std::vector{{1, -1, 2, 1, -1, 2, 1, -1, 1, -1}})); +} \ No newline at end of file diff --git a/task_03/src/topology_sort.cpp b/task_03/src/topology_sort.cpp deleted file mode 100644 index e53f670c..00000000 --- a/task_03/src/topology_sort.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "topology_sort.hpp" diff --git a/task_03/src/topology_sort.hpp b/task_03/src/topology_sort.hpp deleted file mode 100644 index 6f70f09b..00000000 --- a/task_03/src/topology_sort.hpp +++ /dev/null @@ -1 +0,0 @@ -#pragma once diff --git a/task_03/src/weather_report.cpp b/task_03/src/weather_report.cpp new file mode 100644 index 00000000..d2a9c2e8 --- /dev/null +++ b/task_03/src/weather_report.cpp @@ -0,0 +1,22 @@ +#include "weather_report.h" + +#include +#include + +std::vector FindNextGreater(std::vector v) { + std::vector res(v.size(), -1); + std::stack stack; + + for (int i = v.size() - 1; i >= 0; i--) { + while (stack.size() != 0 && v[i] >= v[stack.top()]) { + stack.pop(); + } + if (stack.size() != 0) { + res[i] = stack.top() - i; + } else { + res[i] = -1; + } + stack.push(i); + } + return res; +} \ No newline at end of file diff --git a/task_03/src/weather_report.h b/task_03/src/weather_report.h new file mode 100644 index 00000000..d1ebd320 --- /dev/null +++ b/task_03/src/weather_report.h @@ -0,0 +1,4 @@ +#include +#include + +std::vector FindNextGreater(std::vector v); \ No newline at end of file diff --git a/task_04/src/heap.hpp b/task_04/src/heap.hpp new file mode 100644 index 00000000..18c24c5e --- /dev/null +++ b/task_04/src/heap.hpp @@ -0,0 +1,82 @@ +#include +#include +#include +#include + +template +class BinaryHeap { + public: + BinaryHeap() : data_() {} + BinaryHeap(std::initializer_list _data) : data_(_data) { + for (int i = data_.size() - 1; i >= 0; i--) Heapify(i); + } + void Insert(T new_elem); + + int ExtractMin(); + + void DecreaseKey(int i, T newKey); + + private: + std::vector data_; + int GetParentIndex(int i) { return (i - 1) / 2; } + int GetLefrChildIndex(int i) { return 2 * i + 1; } + int GetRightChildIndex(int i) { return 2 * i + 2; } + + void Heapify(int i); +}; + +template +void BinaryHeap::Insert(T new_elem) { + data_.push_back(new_elem); + int i = data_.size() - 1; + while (i != 0 && data_[GetParentIndex(i)] > data_[i]) { + std::swap(data_[i], data_[GetParentIndex(i)]); + i = GetParentIndex(i); + } +} + +template +void BinaryHeap::DecreaseKey(int i, T new_key) { + if (new_key > data_[i]) { + throw std::logic_error("New element is greater"); + } + data_[i] = new_key; + while (i != 0 && data_[GetParentIndex(i)] > data_[i]) { + swap(data_[i], data_[GetParentIndex(i)]); + i = GetParentIndex(i); + } +} + +template +int BinaryHeap::ExtractMin() { + if (data_.size() == 0) { + throw std::underflow_error("Heap is empty"); + } + if (data_.size() == 1) { + T returning_value = data_[0]; + data_.pop_back(); + return returning_value; + } + int root = data_[0]; + data_[0] = data_[data_.size() - 1]; + data_.pop_back(); + Heapify(0); + return root; +} + +template +void BinaryHeap::Heapify(int i) { + int l = GetLefrChildIndex(i); + int r = GetRightChildIndex(i); + int smallest = i; + if (l < data_.size() && data_[l] < data_[i]) { + smallest = l; + } + if (r < data_.size() && data_[r] < data_[smallest]) { + smallest = r; + } + if (smallest != i) { + std::swap(data_[i], data_[smallest]); + Heapify(smallest); + } +} \ No newline at end of file diff --git a/task_04/src/test.cpp b/task_04/src/test.cpp index 5e11617e..67675131 100644 --- a/task_04/src/test.cpp +++ b/task_04/src/test.cpp @@ -1,6 +1,49 @@ #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include +#include + +TEST(BinaryHeap, Simple) { + BinaryHeap heap; + heap.Insert(37); + heap.Insert(212); + heap.Insert(0); + ASSERT_EQ(heap.ExtractMin(), 0); + ASSERT_EQ(heap.ExtractMin(), 37); + ASSERT_EQ(heap.ExtractMin(), 212); + heap.Insert(34); + ASSERT_EQ(heap.ExtractMin(), 34); + heap.Insert(201); + heap.Insert(0); + heap.Insert(16); + ASSERT_EQ(heap.ExtractMin(), 0); + heap.Insert(345); + ASSERT_EQ(heap.ExtractMin(), 16); + ASSERT_EQ(heap.ExtractMin(), 201); + ASSERT_EQ(heap.ExtractMin(), 345); +} + +TEST(BinaryHeap, Vectors) { + BinaryHeap heap{98, 29, 4, 92, 48, 35, 11, 41, 84, 49}; + ASSERT_EQ(heap.ExtractMin(), 4); + ASSERT_EQ(heap.ExtractMin(), 11); + ASSERT_EQ(heap.ExtractMin(), 29); + ASSERT_EQ(heap.ExtractMin(), 35); + ASSERT_EQ(heap.ExtractMin(), 41); + ASSERT_EQ(heap.ExtractMin(), 48); + ASSERT_EQ(heap.ExtractMin(), 49); + ASSERT_EQ(heap.ExtractMin(), 84); + ASSERT_EQ(heap.ExtractMin(), 92); + ASSERT_EQ(heap.ExtractMin(), 98); +} + +TEST(BinaryHeap, Exceptions) { + BinaryHeap heap; + ASSERT_THROW(heap.ExtractMin(), std::underflow_error); + heap.Insert(12); + heap.Insert(13); + ASSERT_EQ(heap.ExtractMin(), 12); + ASSERT_EQ(heap.ExtractMin(), 13); + ASSERT_THROW(heap.ExtractMin(), std::underflow_error); } diff --git a/task_05/src/quick_sort.hpp b/task_05/src/quick_sort.hpp new file mode 100644 index 00000000..ef0248bf --- /dev/null +++ b/task_05/src/quick_sort.hpp @@ -0,0 +1,12 @@ +#include +#include + +template +void QuickSort(std::vector& v, int low = 0, int high = -1) { + if (high == -1) high = v.size() - 1; + if (low < high) { + int partitionIndex = Partition(v, low, high); + QuickSort(v, low, partitionIndex - 1); + QuickSort(v, partitionIndex + 1, high); + } +} \ No newline at end of file diff --git a/task_05/src/test.cpp b/task_05/src/test.cpp index 5e11617e..098e3fbe 100644 --- a/task_05/src/test.cpp +++ b/task_05/src/test.cpp @@ -1,6 +1,24 @@ #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include + +#include "quick_sort.hpp" + +TEST(QuickSort, Simple) { + std::vector empty; + QuickSort(empty); + ASSERT_EQ(empty, std::vector{}); + std::vector data = {1, 2, 3, 4, 5}; + QuickSort(data); + ASSERT_EQ(data, (std::vector{1, 2, 3, 4, 5})); + data = (std::vector{5, 4, 3, 2, 1}); + QuickSort(data); + ASSERT_EQ(data, (std::vector{1, 2, 3, 4, 5})); + data = (std::vector{3, 4, 2, 1, 5}); + QuickSort(data); + ASSERT_EQ(data, (std::vector{1, 2, 3, 4, 5})); + data = (std::vector{1, 1, 8, 1, 2, 2, 9, 6, 4, 3}); + QuickSort(data); + ASSERT_EQ(data, (std::vector{1, 1, 1, 2, 2, 3, 4, 6, 8, 9})); } diff --git a/task_06/src/n_statistics.hpp b/task_06/src/n_statistics.hpp new file mode 100644 index 00000000..59a859b0 --- /dev/null +++ b/task_06/src/n_statistics.hpp @@ -0,0 +1,20 @@ +#include +#include + +template +int FindNthStatistic(std::vector v, int n) { + int low = 0; + int high = v.size() - 1; + + while (low <= high) { + int partitionIndex = Partition(v, low, high); + if (partitionIndex == n) { + return v[partitionIndex]; + } else if (partitionIndex >= n) { + high = partitionIndex - 1; + } else + low = partitionIndex + 1; + } + + return -1; +} \ No newline at end of file diff --git a/task_06/src/test.cpp b/task_06/src/test.cpp index 5e11617e..f276c28e 100644 --- a/task_06/src/test.cpp +++ b/task_06/src/test.cpp @@ -1,6 +1,22 @@ #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include "n_statistics.hpp" + +TEST(NStatistic, Simple) { + std::vector empty; + ASSERT_EQ(FindNthStatistic(empty, 5), -1); + std::vector v1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + for (int i = 0; i < v1.size(); i++) { + ASSERT_EQ(FindNthStatistic(v1, i), i); + } + std::vector v2 = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; + for (int i = 0; i < v2.size(); i++) { + ASSERT_EQ(FindNthStatistic(v2, i), i); + } + std::vector v3 = {-1, 7, 1, 9, 2, 0, -3, 10, -7, 3}; + std::vector ans = {-7, -3, -1, 0, 1, 2, 3, 7, 9, 10}; + for (int i = 0; i < v3.size(); i++) { + ASSERT_EQ(FindNthStatistic(v3, i), ans[i]); + } } diff --git a/task_07/src/binary_tree.hpp b/task_07/src/binary_tree.hpp new file mode 100644 index 00000000..cd3c92aa --- /dev/null +++ b/task_07/src/binary_tree.hpp @@ -0,0 +1,205 @@ +#include +#include + +template +struct Node { + Node(T value) : data(value), left_ptr(nullptr), right_ptr(nullptr) {} + T data; + Node* left_ptr; + Node* right_ptr; + int height; +}; + +template +class BinaryTree { + public: + BinaryTree() : root_(nullptr) {} + ~BinaryTree() { DestroyTree(root_); } + + void Insert(int value) { root_ = InsertRecursive(root_, value); } + + bool Search(int value) { return SearchRecursive(root_, value); } + + std::vector InorderTraversal(); + std::vector PreorderTraversal(); + std::vector PostorderTraversal(); + + private: + Node* root_; + Node* InsertRecursive(Node* node, int value); + bool SearchRecursive(Node* node, int value); + void InorderTraversalRecursive(Node* node, std::vector& ans); + void PreorderTraversalRecursive(Node* node, std::vector& ans); + void PostorderTraversalRecursive(Node* node, std::vector& ans); + void DestroyTree(Node* node); + int GetHeight(Node* node); + int GetBalance(Node* node); + void UpdateHeight(Node* node); + Node* RotateRight(Node* node); + Node* RotateLeft(Node* node); + Node* Balance(Node* node); +}; + +template +std::vector BinaryTree::InorderTraversal() { + std::vector ans; + InorderTraversalRecursive(root_, ans); + return ans; +} + +template +std::vector BinaryTree::PreorderTraversal() { + std::vector ans; + PreorderTraversalRecursive(root_, ans); + return ans; +} + +template +std::vector BinaryTree::PostorderTraversal() { + std::vector ans; + PostorderTraversalRecursive(root_, ans); + return ans; +} + +template +void BinaryTree::InorderTraversalRecursive(Node* node, + std::vector& ans) { + if (node == nullptr) { + return; + } + InorderTraversalRecursive(node->left_ptr, ans); + ans.push_back(node->data); + InorderTraversalRecursive(node->right_ptr, ans); +} + +template +void BinaryTree::PreorderTraversalRecursive(Node* node, + std::vector& ans) { + if (node == nullptr) { + return; + } + ans.push_back(node->data); + PreorderTraversalRecursive(node->left_ptr, ans); + PreorderTraversalRecursive(node->right_ptr, ans); +} + +template +void BinaryTree::PostorderTraversalRecursive(Node* node, + std::vector& ans) { + if (node == nullptr) { + return; + } + PostorderTraversalRecursive(node->left_ptr, ans); + PostorderTraversalRecursive(node->right_ptr, ans); + ans.push_back(node->data); +} + +template +bool BinaryTree::SearchRecursive(Node* node, int value) { + if (node == nullptr) { + return false; + } + + if (value == node->data) { + return true; + } + + if (value < node->data) { + return SearchRecursive(node->left_ptr, value); + } else { + return SearchRecursive(node->right_ptr, value); + } +} + +template +Node* BinaryTree::InsertRecursive(Node* node, int value) { + if (node == nullptr) { + return new Node(value); + } + + if (value < node->data) { + node->left_ptr = InsertRecursive(node->left_ptr, value); + } else if (value > node->data) { + node->right_ptr = InsertRecursive(node->right_ptr, value); + } + return Balance(node); +} + +template +void BinaryTree::DestroyTree(Node* node) { + if (node == nullptr) { + return; + } + + DestroyTree(node->left_ptr); + DestroyTree(node->right_ptr); + delete node; +} + +template +int BinaryTree::GetHeight(Node* node) { + if (node == nullptr) return 0; + return node->height; +} + +template +int BinaryTree::GetBalance(Node* node) { + if (node == nullptr) return 0; + return GetHeight(node->left_ptr) - GetHeight(node->right_ptr); +} + +template +void BinaryTree::UpdateHeight(Node* node) { + node->height = + std::max(GetHeight(node->left_ptr), GetHeight(node->right_ptr)) + 1; +} + +template +Node* BinaryTree::RotateRight(Node* node) { + Node* l_child = node->left_ptr; + Node* lr_child = l_child->right_ptr; + + l_child->right_ptr = node; + node->left_ptr = lr_child; + + UpdateHeight(node); + UpdateHeight(l_child); + + return l_child; +} + +template +Node* BinaryTree::RotateLeft(Node* node) { + Node* r_child = node->right_ptr; + Node* rl_child = r_child->left_ptr; + + r_child->left_ptr = node; + node->right_ptr = rl_child; + + UpdateHeight(node); + UpdateHeight(r_child); + + return r_child; +} + +template +Node* BinaryTree::Balance(Node* node) { + UpdateHeight(node); + + int balance = GetBalance(node); + + if (balance > 1) { + if (GetBalance(node->left_ptr) < 0) { + node->left_ptr = RotateLeft(node->left_ptr); + } + return RotateRight(node); + } + if (balance < -1) { + if (GetBalance(node->right_ptr) > 0) { + node->right_ptr = RotateRight(node->right_ptr); + } + return RotateLeft(node); + } + + return node; +} diff --git a/task_07/src/main.cpp b/task_07/src/main.cpp index 0e4393ba..de20bc4a 100644 --- a/task_07/src/main.cpp +++ b/task_07/src/main.cpp @@ -1,3 +1,6 @@ +#include #include -int main() { return 0; } +using namespace std; + +int main(void) { return 0; } \ No newline at end of file diff --git a/task_07/src/test.cpp b/task_07/src/test.cpp index 5e11617e..68248427 100644 --- a/task_07/src/test.cpp +++ b/task_07/src/test.cpp @@ -1,6 +1,20 @@ #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include "binary_tree.hpp" + +TEST(BinaryTree, Total) { + BinaryTree tree; + std::vector data = {35, 38, 12, 30, 25, 22, 18, 21, 39, 13, 40}; + for (int i = 0; i < data.size(); i++) tree.Insert(data[i]); + for (int i = -40; i <= 40; i++) { + bool ans = std::find(data.begin(), data.end(), i) != data.end(); + ASSERT_EQ(tree.Search(i), ans); + } + std::vector ans_in = {12, 13, 18, 21, 22, 25, 30, 35, 38, 39, 40}; + std::vector ans_pre = {25, 18, 12, 13, 22, 21, 35, 30, 38, 39, 40}; + std::vector ans_post = {13, 12, 21, 22, 18, 30, 40, 39, 38, 35, 25}; + ASSERT_EQ(tree.InorderTraversal(), ans_in); + ASSERT_EQ(tree.PreorderTraversal(), ans_pre); + ASSERT_EQ(tree.PostorderTraversal(), ans_post); } diff --git a/task_08/src/hash_table.hpp b/task_08/src/hash_table.hpp new file mode 100644 index 00000000..224b99b5 --- /dev/null +++ b/task_08/src/hash_table.hpp @@ -0,0 +1,99 @@ +#include +#include +#include +#include +#include + +template +class HashTable { + public: + HashTable(size_t size = 10) : table_(size), load_factor_(0.0) {} + + void Insert(const Key& key, const Value& value); + + bool Search(const Key& key); + Value Get(const Key& key); + + bool Erase(const Key& key); + + size_t Size() const; + + private: + void Rehash(); + std::vector>> table_; + std::hash hash_; + double load_factor_; +}; + +template +void HashTable::Insert(const Key& key, const Value& value) { + if (load_factor_ >= 0.75) { + Rehash(); + } + size_t index = hash_(key) % table_.size(); + for (auto& pair : table_[index]) { + if (pair.first == key) { + pair.second = value; + return; + } + } + table_[index].emplace_back(key, value); + load_factor_ = static_cast(Size()) / table_.size(); +} + +template +bool HashTable::Search(const Key& key) { + size_t index = hash_(key) % table_.size(); + for (const auto& pair : table_[index]) { + if (pair.first == key) { + return true; + } + } + return false; +} + +template +Value HashTable::Get(const Key& key) { + size_t index = hash_(key) % table_.size(); + for (const auto& pair : table_[index]) { + if (pair.first == key) { + return pair.second; + } + } + throw std::out_of_range("No such key in table"); +} + +template +bool HashTable::Erase(const Key& key) { + size_t index = hash_(key) % table_.size(); + for (auto it = table_[index].begin(); it != table_[index].end(); ++it) { + if (it->first == key) { + table_[index].erase(it); + load_factor_ = static_cast(Size()) / table_.size(); + return true; + } + } + return false; +} + +template +size_t HashTable::Size() const { + size_t count = 0; + for (const auto& list : table_) { + count += list.size(); + } + return count; +} + +template +void HashTable::Rehash() { + std::vector>> new_table(table_.size() * 2); + for (auto& list : table_) { + for (auto& pair : list) { + size_t index = hash_(pair.first) % new_table.size(); + new_table[index].emplace_back(std::move(pair)); + } + } + table_ = std::move(new_table); + load_factor_ = static_cast(Size()) / table_.size(); +} \ No newline at end of file diff --git a/task_08/src/test.cpp b/task_08/src/test.cpp index 5e11617e..f279d523 100644 --- a/task_08/src/test.cpp +++ b/task_08/src/test.cpp @@ -1,6 +1,37 @@ #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include +#include + +#include "hash_table.hpp" + +TEST(HashTable, Simple) { + HashTable table; + std::vector keys = { + "Lobachevskiy", "Euler", "Ferma", "Lagrange", "Burbaki", + "Kholmogorov", "Landau", "Raigorodskiy", "Vinberg", "Arnold"}; + std::vector values = {1792, 1707, 1601, 1736, 1935, + 1903, 1908, 1976, 1937, 1937}; + for (int i = 0; i < keys.size(); i++) { + table.Insert(keys[i], values[i]); + } + for (int i = 0; i < keys.size(); i++) { + ASSERT_EQ(table.Search(keys[i]), true); + ASSERT_EQ(table.Get(keys[i]), values[i]); + } + ASSERT_EQ(table.Search("Gauss"), false); + ASSERT_EQ(table.Search("Newton"), false); + ASSERT_EQ(table.Search("Bool"), false); + ASSERT_EQ(table.Search("Koshi"), false); + ASSERT_EQ(table.Search("Abele"), false); + for (int i = 0; i < keys.size() / 2; i++) { + table.Erase(keys[i]); + } + for (int i = 0; i < keys.size() / 2; i++) { + ASSERT_EQ(table.Search(keys[i]), false); + } + for (int i = keys.size() / 2; i < keys.size(); i++) { + ASSERT_EQ(table.Search(keys[i]), true); + } } diff --git a/task_09/src/min_coins.cpp b/task_09/src/min_coins.cpp new file mode 100644 index 00000000..525f6dd6 --- /dev/null +++ b/task_09/src/min_coins.cpp @@ -0,0 +1,18 @@ +#include +#include +#include + +int MinCoins(int amount, const std::vector& coins) { + std::vector dp(amount + 1, amount + 1); + dp[0] = 0; + + for (int i = 1; i <= amount; i++) { + for (int coin : coins) { + if (coin <= i) { + dp[i] = std::min(dp[i], dp[i - coin] + 1); + } + } + } + + return (dp[amount] > amount) ? -1 : dp[amount]; +} diff --git a/task_09/src/min_coins.hpp b/task_09/src/min_coins.hpp new file mode 100644 index 00000000..8a771fc7 --- /dev/null +++ b/task_09/src/min_coins.hpp @@ -0,0 +1,5 @@ +#include +#include +#include + +int MinCoins(int amount, const std::vector& coins); \ No newline at end of file diff --git a/task_09/src/test.cpp b/task_09/src/test.cpp index 869094dd..66f147ef 100644 --- a/task_09/src/test.cpp +++ b/task_09/src/test.cpp @@ -1,4 +1,18 @@ #include -TEST(TopologySort, Simple) { ASSERT_EQ(1, 1); } +#include "min_coins.hpp" + +TEST(Coins, Simple) { + ASSERT_EQ(3, MinCoins(14, (std::vector{1, 2, 5, 10}))); + ASSERT_EQ(4, MinCoins(19, (std::vector{1, 2, 5, 10}))); + ASSERT_EQ(4, MinCoins(100, std::vector{1, 5, 10, 25})); + ASSERT_EQ(10, MinCoins(500, std::vector{1, 5, 10, 25, 50})); + ASSERT_EQ(-1, MinCoins(3, std::vector{5, 7, 9})); + ASSERT_EQ(3, MinCoins(11, std::vector{2, 5, 7})); + ASSERT_EQ(0, MinCoins(0, std::vector{1, 2, 5, 10})); + ASSERT_EQ(1, MinCoins(14, std::vector{14})); + ASSERT_EQ(1, MinCoins(1, std::vector{1})); + ASSERT_EQ(2, MinCoins(12, std::vector{2, 2, 5, 10})); + ASSERT_EQ(3, MinCoins(16, std::vector{1, 5, 5, 10})); +}