diff --git a/task_01/src/get_terms.hpp b/task_01/src/get_terms.hpp new file mode 100644 index 0000000..f55a6ee --- /dev/null +++ b/task_01/src/get_terms.hpp @@ -0,0 +1,29 @@ +#include +#include +#include +#include + +using namespace std; + +pair get_terms(vector v, int S) { + int N = v.size(); + + if (N == 0 || N == 1) return pair(-1, -1); + + int l{0}, r{N - 1}; + + int s; + while (l != r) { + s = v[l] + v[r]; + if (s == S) { + return pair(v[l], v[r]); + } else { + if (s > S) + --r; + else + ++l; + } + } + + return pair(-1, -1); +} \ No newline at end of file diff --git a/task_01/src/main.cpp b/task_01/src/main.cpp index 0e4393b..d9302c5 100644 --- a/task_01/src/main.cpp +++ b/task_01/src/main.cpp @@ -1,3 +1,34 @@ +#include #include +#include +#include +#include -int main() { return 0; } +using namespace std; + +int main() { + int S, N; + vector v; + string line3, line1, line2; + + getline(cin, line1); + getline(cin, line2); + getline(cin, line3); + + S = stoi(line1); + N = stoi(line2); + + istringstream is(line3); + + int x; + while (is >> x) v.push_back(x); + pair result = get_terms(v, S); + if (result == pair(-1, -1)) + cout << -1 << endl; + else + cout << result.first << " " << result.second << endl; + /* + python3 ./scripts/run_cases.py --tasks task_01 + */ + return 0; +} diff --git a/task_01/src/test.cpp b/task_01/src/test.cpp index 87cef73..e0d92f2 100644 --- a/task_01/src/test.cpp +++ b/task_01/src/test.cpp @@ -1,5 +1,35 @@ #include +#include +#include +#include + TEST(Test, Simple) { - ASSERT_EQ(1, 1); // Stack [] + std::vector v = {1, 2, 4}; + std::vector v1 = {2, 7, 11, 15}; + std::vector v2 = {3, 7, 12}; + std::vector v3 = {-67, -42, 0, 52, 108, 252}; + std::vector v4 = {2, 4}; + ASSERT_EQ(get_terms(v, 52), std::make_pair(-1, -1)); + ASSERT_EQ(get_terms(v, -52), std::make_pair(-1, -1)); + ASSERT_EQ(get_terms(v, 0), std::make_pair(-1, -1)); + ASSERT_EQ(get_terms(v1, 9), std::make_pair(2, 7)); + ASSERT_EQ(get_terms(v2, 19), std::make_pair(7, 12)); + ASSERT_EQ(get_terms(v3, 10), std::make_pair(-42, 52)); + ASSERT_EQ(get_terms(v3, 1), std::make_pair(-1, -1)); + ASSERT_EQ(get_terms(v4, 6), std::make_pair(2, 4)); +} + +TEST(Test, Empty) { + std::vector v_empty = {}; + ASSERT_EQ(get_terms(v_empty, 52), std::make_pair(-1, -1)); + ASSERT_EQ(get_terms(v_empty, -52), std::make_pair(-1, -1)); + ASSERT_EQ(get_terms(v_empty, 0), std::make_pair(-1, -1)); +} + +TEST(Test, Single) { + std::vector v_single = {0}; + ASSERT_EQ(get_terms(v_single, 52), std::make_pair(-1, -1)); + ASSERT_EQ(get_terms(v_single, -52), std::make_pair(-1, -1)); + ASSERT_EQ(get_terms(v_single, 0), std::make_pair(-1, -1)); } \ No newline at end of file diff --git a/task_02/src/get_border_index.hpp b/task_02/src/get_border_index.hpp new file mode 100644 index 0000000..ea0bb0e --- /dev/null +++ b/task_02/src/get_border_index.hpp @@ -0,0 +1,22 @@ +#include + +using namespace std; + +int get_border_index(vector v) { + int N = v.size(); + + if (v[1] == 1) return 0; + if (v[N - 2] == 0) return N - 2; + + int left = 0, right = N - 1; + + while (left + 1 < right) { + int mid = (left + right) / 2; + + if (v[mid] == 1) + right = mid; + else + left = mid; + } + return left; +} \ No newline at end of file diff --git a/task_02/src/main.cpp b/task_02/src/main.cpp index 0e4393b..d78999d 100644 --- a/task_02/src/main.cpp +++ b/task_02/src/main.cpp @@ -1,3 +1,53 @@ +#include #include +#include +#include +#include -int main() { return 0; } +using namespace std; + +int main() { + int N; + vector v; + string line1, line2; + + getline(cin, line1); + getline(cin, line2); + + N = stoi(line1); + + istringstream is(line2); + int x; + while (is >> x) v.push_back(x); + + cout << get_border_index(v) << endl; + /* + if (v[1] == 1) cout << 0 << endl; + else if (v[N-2] == 0) cout << N-2 << endl; + else + { + int i{(N-1)/2}; + while (v[i] != 0 && v[i+1] != 1) + { + if (v[i] == 0) + { + if (i+1 < v.size() && v[i+1] == 1) + { + cout << i << endl; + break; + } + i = (N-1 - i)/2; + } else + { + if (i-1 >= 0 && v[i-1] == 0) + { + cout << i-1 << endl; + break; + } + i /= 2; + } + } + }; + */ + return 0; +} diff --git a/task_02/src/test.cpp b/task_02/src/test.cpp index ee23770..01c0d20 100644 --- a/task_02/src/test.cpp +++ b/task_02/src/test.cpp @@ -1,5 +1,34 @@ #include +#include + TEST(Test, Simple) { - ASSERT_EQ(1, 1); // placeholder + vector v1{0, 1}; + vector v2{0, 0, 0, 1, 1}; + vector v3{0, 0, 0, 0, 0, 1}; + vector v4{0, 1, 1, 1, 1}; + vector v5{0, 0, 1, 1, 1, 1}; + vector v6{0, 0, 0, 1}; + vector v7{0, 0, 1}; + vector v8{0, 1, 1}; + vector v9{0, 0, 0, 0, 1, 1, 1}; + vector v10{0, 0, 0, 0, 0, 0, 0, 0, 1}; + vector v11{0, 0, 0, 0, 1}; + vector v12{0, 0, 1, 1}; + vector v13{0, 1, 1, 1}; + vector v14{0, 1, 0, 1, 0, 1, 0, 1}; + + ASSERT_EQ(get_border_index(v1), 0); + ASSERT_EQ(get_border_index(v2), 2); + ASSERT_EQ(get_border_index(v3), 4); + ASSERT_EQ(get_border_index(v4), 0); + ASSERT_EQ(get_border_index(v5), 1); + ASSERT_EQ(get_border_index(v6), 2); + ASSERT_EQ(get_border_index(v7), 1); + ASSERT_EQ(get_border_index(v8), 0); + ASSERT_EQ(get_border_index(v9), 3); + ASSERT_EQ(get_border_index(v10), 7); + ASSERT_EQ(get_border_index(v11), 3); + ASSERT_EQ(get_border_index(v12), 1); + ASSERT_EQ(get_border_index(v13), 0); } diff --git a/task_03/src/get_combinations.hpp b/task_03/src/get_combinations.hpp new file mode 100644 index 0000000..0db3b5a --- /dev/null +++ b/task_03/src/get_combinations.hpp @@ -0,0 +1,40 @@ +#include +#include + +using namespace std; + +const vector v_s{"abc", "def", "ghi", "jkl", + "mno", "pqrs", "tuv", "wxyz"}; +constexpr int shift = 2; + +void get_small_combination(vector nums, int i, string s, + vector &result) { + if (i == nums.size()) { + result.push_back(s); + return; + } + + string s_new; + for (char c : v_s[nums[i] - shift]) { + s_new = s + c; + get_small_combination(nums, i + 1, s_new, result); + } +} + +vector get_combinations(string digits) { + vector nums; + for (char c : digits) { + if (c >= '2' && c <= '9') { + nums.push_back(c - '0'); + } + } + vector result; + + if (nums.empty()) return result; + + string s; + int i = 0; + + get_small_combination(nums, i, s, result); + return result; +} \ No newline at end of file diff --git a/task_03/src/main.cpp b/task_03/src/main.cpp index 0e4393b..f94d169 100644 --- a/task_03/src/main.cpp +++ b/task_03/src/main.cpp @@ -1,3 +1,15 @@ +#include #include +#include +#include -int main() { return 0; } +using namespace std; + +int main() { + string digits; + getline(cin, digits); + + vector result = get_combinations(digits); + + for (string str : result) cout << str << " "; +} diff --git a/task_03/src/test.cpp b/task_03/src/test.cpp index 869094d..9bda217 100644 --- a/task_03/src/test.cpp +++ b/task_03/src/test.cpp @@ -1,4 +1,14 @@ - #include +#include + +#include "get_combinations.hpp" + +using namespace std; + TEST(TopologySort, Simple) { ASSERT_EQ(1, 1); } + +TEST(TopologySort, Single) { + ASSERT_EQ(get_combinations("2"), 1); + ASSERT_EQ(get_combinations("1"), ""); +} diff --git a/task_04/src/stack.cpp b/task_04/src/stack.cpp index 8ca8990..fd732b6 100644 --- a/task_04/src/stack.cpp +++ b/task_04/src/stack.cpp @@ -1,21 +1,26 @@ #include "stack.hpp" -#include - -void Stack::Push(int value) { data_.push(value); } +void Stack::Push(int value) { stack_.push_back(value); } int Stack::Pop() { - auto result = data_.top(); - data_.pop(); + auto result = stack_.back(); + stack_.pop_back(); return result; } -void MinStack::Push(int value) { data_.push_back(value); } +void MinStack::Push(int value) { + stack_.push_back(value); + if (min_stack_.size() == 0 || value < min_stack_.back()) + min_stack_.push_back(value); + else + min_stack_.push_back(min_stack_.back()); +} int MinStack::Pop() { - auto result = data_.back(); - data_.pop_back(); + auto result = stack_.back(); + stack_.pop_back(); + min_stack_.pop_back(); return result; } -int MinStack::GetMin() { return *std::min_element(data_.begin(), data_.end()); } \ No newline at end of file +int MinStack::GetMin() { return min_stack_.back(); } \ No newline at end of file diff --git a/task_04/src/stack.hpp b/task_04/src/stack.hpp index 138ec40..cbcdf7f 100644 --- a/task_04/src/stack.hpp +++ b/task_04/src/stack.hpp @@ -9,7 +9,7 @@ class Stack { int Pop(); private: - std::stack data_; + std::vector stack_; }; class MinStack { @@ -19,5 +19,6 @@ class MinStack { int GetMin(); private: - std::vector data_; + std::vector stack_; + std::vector min_stack_; }; diff --git a/task_05/src/main.cpp b/task_05/src/main.cpp index 0e4393b..5d8399e 100644 --- a/task_05/src/main.cpp +++ b/task_05/src/main.cpp @@ -1,3 +1,20 @@ #include +#include -int main() { return 0; } +#include "topology_sort.hpp" + +using namespace std; + +int main() { + int N; + cin >> N; + vector v; + + for (int i = 0; i < N; ++i) { + int n; + cin >> n; + v.push_back(n); + } + vector v2 = temperature_rise(v); + for (int t : v2) cout << t << " "; +} diff --git a/task_05/src/test.cpp b/task_05/src/test.cpp index ef5a86a..44fb6c7 100644 --- a/task_05/src/test.cpp +++ b/task_05/src/test.cpp @@ -1,8 +1,36 @@ #include +#include + #include "topology_sort.hpp" TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] + vector v1{1, 2, 3, 4, 5, 6}; + vector v01{1, 1, 1, 1, 1, 0}; + vector v2{67, 52, 42, 13, 2}; + vector v02{0, 0, 0, 0, 0}; + vector v3{52, 52, 52, 52, 52}; + vector v4{23, 24, 25, 21, 29, 22, 26, 23}; + vector v04{1, 1, 4, 2, 1, 1, 0, 0}; + vector v5{-13, -5, 10, 10, 0, -3, -2, 4, -10}; + vector v05{1, 1, 0, 0, 3, 1, 1, 0}; + + ASSERT_EQ(temperature_rise(v1), v01); // по возрастанию + ASSERT_EQ(temperature_rise(v2), v02); // по убыванию + ASSERT_EQ(temperature_rise(v3), v02); // одинаковые числа + ASSERT_EQ(temperature_rise(v4), v04); // обычный + ASSERT_EQ(temperature_rise(v5), v05); // с отрицательными числами +} + +TEST(TopologySort, Single) { + vector v{52}; + vector v0{0}; + ASSERT_EQ(temperature_rise(v), v0); +} + +TEST(TopologySort, Empty) { + vector v{}; + vector v0{}; + ASSERT_EQ(temperature_rise(v), v0); } diff --git a/task_05/src/topology_sort.cpp b/task_05/src/topology_sort.cpp deleted file mode 100644 index e53f670..0000000 --- a/task_05/src/topology_sort.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "topology_sort.hpp" diff --git a/task_05/src/topology_sort.hpp b/task_05/src/topology_sort.hpp index 6f70f09..6e8b37f 100644 --- a/task_05/src/topology_sort.hpp +++ b/task_05/src/topology_sort.hpp @@ -1 +1,22 @@ -#pragma once +#include + +using namespace std; + +vector temperature_rise(vector v1) { + vector stack, v2(v1.size(), 0); + + size_t i = 0; + while (i < v1.size()) { + if (stack.size() == 0) { + stack.push_back(i); + ++i; + } else if (v1[i] > v1[stack.back()]) { + v2[stack.back()] = i - stack.back(); + stack.pop_back(); + } else { + stack.push_back(i); + ++i; + } + } + return v2; +} \ No newline at end of file diff --git a/task_06/src/get_min_cost.hpp b/task_06/src/get_min_cost.hpp new file mode 100644 index 0000000..bd25ae2 --- /dev/null +++ b/task_06/src/get_min_cost.hpp @@ -0,0 +1,15 @@ +#include + +using namespace std; + +double get_min_cost(int K, vector fish_cost) { + vector min_costs; + int left = 0; + for (int i = 0; i < fish_cost.size(); ++i) { + if (i == 0) continue; // min_costs.push_back(fish_cost[0]); + + if (fish_cost[i] <= fish_cost[i - 1]) // min_costs.back()) + // min_costs.push_back(fish_cost[i]); + else min_costs.push_back(min_costs.back()); + } +} \ No newline at end of file diff --git a/task_06/src/main.cpp b/task_06/src/main.cpp index 0e4393b..9a0f219 100644 --- a/task_06/src/main.cpp +++ b/task_06/src/main.cpp @@ -1,3 +1,10 @@ #include +#include +#include "get_min_cost.hpp -int main() { return 0; } +using namespace std; + +int main() { + int N, K; + cin >> N >> K; +} diff --git a/task_07/src/MergeSort.hpp b/task_07/src/MergeSort.hpp new file mode 100644 index 0000000..67914d3 --- /dev/null +++ b/task_07/src/MergeSort.hpp @@ -0,0 +1,42 @@ +#include + +using namespace std; + +vector MergeSort(vector v) { + int n = v.size(); + if (n == 1 || n == 0) return v; + + vector v_sorted; + + // Деление на две части + vector v1(v.begin(), v.begin() + n / 2); + vector v2(v.begin() + n / 2, v.end()); + + vector v1_sorted = MergeSort(v1); + vector v2_sorted = MergeSort(v2); + + // Слияние + size_t ptr1 = 0, ptr2 = 0; + + while (ptr1 < v1.size() && ptr2 < v2.size()) { + if (v1_sorted[ptr1] > v2_sorted[ptr2]) { + v_sorted.push_back(v2_sorted[ptr2]); + ++ptr2; + } else { + v_sorted.push_back(v1_sorted[ptr1]); + ++ptr1; + } + } + + // Добавление оставшихся элементов + while (ptr1 < v1_sorted.size()) { + v_sorted.push_back(v1_sorted[ptr1]); + ++ptr1; + } + + while (ptr2 < v2_sorted.size()) { + v_sorted.push_back(v2_sorted[ptr2]); + ++ptr2; + } + return v_sorted; +} \ No newline at end of file diff --git a/task_07/src/main.cpp b/task_07/src/main.cpp index 0e4393b..db72c41 100644 --- a/task_07/src/main.cpp +++ b/task_07/src/main.cpp @@ -1,3 +1,20 @@ +#include #include +#include -int main() { return 0; } +using namespace std; + +int main() { + int N; + cin >> N; + vector v; + + for (int i = 0; i < N; ++i) { + int n; + cin >> n; + v.push_back(n); + } + vector v_sorted = MergeSort(v); + + for (int i = 0; i < N; ++i) cout << v_sorted[i] << " "; +} diff --git a/task_07/src/test.cpp b/task_07/src/test.cpp index 5e11617..ca94fc0 100644 --- a/task_07/src/test.cpp +++ b/task_07/src/test.cpp @@ -1,6 +1,32 @@ - #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include +#include + +TEST(MergeSort, Simple) { + vector v1{1, 2, 3, 4, 5}; + vector v2{5, 3, 1, 4, 2}; + vector v3{5, 3, -7, 4, -2, 0}; + vector v03{-7, -2, 0, 3, 4, 5}; + vector v4{1, 1, 42, 0, 42, 42, 52, 42, 67, 52, -52, -52, -52}; + vector v04{-52, -52, -52, 0, 1, 1, 42, 42, 42, 42, 52, 52, 67}; + vector v5{15000, 20, 17, 13, 10, 8, 5, 2, -1, -52}; + vector v05{-52, -1, 2, 5, 8, 10, 13, 17, 20, 15000}; + + ASSERT_EQ(MergeSort(v1), v1); // уже отсортированный + ASSERT_EQ(MergeSort(v2), v1); // нечетное количество элементов + ASSERT_EQ(MergeSort(v3), + v03); // четное количество элементов + отрицательные числа + ASSERT_EQ(MergeSort(v4), v04); // c повторяющимися числами + ASSERT_EQ(MergeSort(v5), v05); // обратный } + +TEST(MergeSort, Empty) { + std::vector v_empty = {}; + ASSERT_EQ(MergeSort(v_empty), v_empty); +} + +TEST(Test, Single) { + std::vector v_single = {52}; + ASSERT_EQ(MergeSort(v_single), v_single); +} \ No newline at end of file diff --git a/task_08/src/get_k_element.hpp b/task_08/src/get_k_element.hpp new file mode 100644 index 0000000..3b06ba8 --- /dev/null +++ b/task_08/src/get_k_element.hpp @@ -0,0 +1,28 @@ +#include +#include + +using namespace std; + +int get_k_element(vector v, int K, int left, int right) { + int pivot = right; + + for (int i = left; i < right; ++i) { + if (pivot > i) { + if (v[i] > v[pivot]) { + swap(v[i], v[pivot]); + pivot = i; + } + } else { + if (v[i] < v[pivot]) { + swap(v[i], v[pivot]); + pivot = i; + } + } + } + + if (pivot + 1 == K) return v[pivot]; + if (pivot + 1 > K) + return get_k_element(v, K, left, pivot - 1); + else + return get_k_element(v, K, pivot + 1, right); +} \ No newline at end of file diff --git a/task_08/src/main.cpp b/task_08/src/main.cpp index 0e4393b..9534489 100644 --- a/task_08/src/main.cpp +++ b/task_08/src/main.cpp @@ -1,3 +1,22 @@ #include +#include -int main() { return 0; } +#include "get_k_element.hpp" + +using namespace std; + +int main() { + int N, K; + cin >> N >> K; + + vector v; + + for (int i = 0; i < N; ++i) { + int n; + cin >> n; + v.push_back(n); + } + + int left{0}, right(N - 1); + cout << get_k_element(v, K, left, right) << endl; +} diff --git a/task_08/src/test.cpp b/task_08/src/test.cpp index 5e11617..2854e00 100644 --- a/task_08/src/test.cpp +++ b/task_08/src/test.cpp @@ -1,6 +1,82 @@ - #include +#include +#include + +using namespace std; + TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] + vector v1{0, 1}; + vector v2{0, 0, 0, 1, 1}; + vector v3{0, 0, 0, 0, 0, 1}; + vector v4{0, 1, 1, 1, 1}; + vector v5{0, 0, 1, 1, 1, 1}; + + ASSERT_EQ(get_k_element(v1, 1, 0, v1.size() - 1), 0); + ASSERT_EQ(get_k_element(v2, 1, 0, v2.size() - 1), 0); + ASSERT_EQ(get_k_element(v3, 1, 0, v3.size() - 1), 0); + ASSERT_EQ(get_k_element(v4, 1, 0, v4.size() - 1), 0); + ASSERT_EQ(get_k_element(v5, 1, 0, v5.size() - 1), 0); + + ASSERT_EQ(get_k_element(v1, 2, 0, v1.size() - 1), 1); + ASSERT_EQ(get_k_element(v2, 5, 0, v2.size() - 1), 1); + ASSERT_EQ(get_k_element(v3, 6, 0, v3.size() - 1), 1); + + ASSERT_EQ(get_k_element(v2, 3, 0, v2.size() - 1), 0); + ASSERT_EQ(get_k_element(v4, 3, 0, v4.size() - 1), 1); + ASSERT_EQ(get_k_element(v5, 4, 0, v5.size() - 1), 1); +} + +TEST(Test, DifferentNumbers) { + // положительные числа + vector v1{7, 10, 4, 3, 20}; + ASSERT_EQ(get_k_element(v1, 1, 0, v1.size() - 1), 3); + ASSERT_EQ(get_k_element(v1, 3, 0, v1.size() - 1), 7); + ASSERT_EQ(get_k_element(v1, 5, 0, v1.size() - 1), 20); + + // отрицательные числа + vector v2{-5, -2, -8, -1, -3}; + ASSERT_EQ(get_k_element(v2, 1, 0, v2.size() - 1), -8); + ASSERT_EQ(get_k_element(v2, 3, 0, v2.size() - 1), -3); + ASSERT_EQ(get_k_element(v2, 5, 0, v2.size() - 1), -1); + + // положительные и отрицательные + vector v3{-10, 5, -3, 8, 0, -7, 2}; + ASSERT_EQ(get_k_element(v3, 1, 0, v3.size() - 1), -10); + ASSERT_EQ(get_k_element(v3, 4, 0, v3.size() - 1), 0); + ASSERT_EQ(get_k_element(v3, 7, 0, v3.size() - 1), 8); + + // повторяющиеся элементы + vector v4{5, 5, 5, 1, 1, 9, 9, 9, 9}; + ASSERT_EQ(get_k_element(v4, 1, 0, v4.size() - 1), 1); + ASSERT_EQ(get_k_element(v4, 3, 0, v4.size() - 1), 5); + ASSERT_EQ(get_k_element(v4, 6, 0, v4.size() - 1), 9); + ASSERT_EQ(get_k_element(v4, 9, 0, v4.size() - 1), 9); } + +TEST(Test, TooSimple) { + // один элемент + vector v1{42}; + ASSERT_EQ(get_k_element(v1, 1, 0, 0), 42); + + // два элемента + vector v2{100, 200}; + ASSERT_EQ(get_k_element(v2, 1, 0, 1), 100); + ASSERT_EQ(get_k_element(v2, 2, 0, 1), 200); + + // два одинаковых элемента + vector v3{7, 7}; + ASSERT_EQ(get_k_element(v3, 1, 0, 1), 7); + ASSERT_EQ(get_k_element(v3, 2, 0, 1), 7); + + // одинаковые + vector v4{3, 3, 3, 3, 3}; + for (int k = 1; k <= 5; k++) { + ASSERT_EQ(get_k_element(v4, k, 0, v4.size() - 1), 3); + } + + vector v5{-1, 0, -1, 0, -2}; + ASSERT_EQ(get_k_element(v5, 1, 0, v5.size() - 1), -2); + ASSERT_EQ(get_k_element(v5, 3, 0, v5.size() - 1), -1); + ASSERT_EQ(get_k_element(v5, 5, 0, v5.size() - 1), 0); +} \ No newline at end of file diff --git a/task_09/src/splay_tree.cpp b/task_09/src/splay_tree.cpp new file mode 100644 index 0000000..3563ac2 --- /dev/null +++ b/task_09/src/splay_tree.cpp @@ -0,0 +1,164 @@ +#include "splay_tree.hpp" + +#include + +void SplayTree::rotateLeft(Node* n) { + Node* m = n->right; + if (!m) return; + + Node* parent = n->parent; + n->right = m->left; + if (m->left) m->left->parent = n; + + m->left = n; + n->parent = m; + m->parent = parent; + + if (parent) { + if (parent->left == n) + parent->left = m; + else + parent->right = m; + } else + root = m; +} + +void SplayTree::rotateRight(Node* n) { + Node* m = n->left; + if (!m) return; + + Node* parent = n->parent; + n->left = m->right; + if (m->right) m->right->parent = n; + + m->right = n; + n->parent = m; + m->parent = parent; + + if (parent) { + if (parent->left == n) + parent->left = m; + else + parent->right = m; + } else + root = m; +} + +void SplayTree::Splay(Node* n) { + if (!n->parent) return; + + if (!n->parent->parent) { + if (n->parent->left == n) + rotateRight(n->parent); + else + rotateLeft(n->parent); + return; + } + if (n->parent->right == n) { + if (n->parent->parent->right == n->parent) { + rotateLeft(n->parent->parent); + rotateLeft(n->parent); + } else { + rotateLeft(n->parent); + rotateRight(n->parent); + } + } else { + if (n->parent->parent->left == n->parent) { + rotateRight(n->parent->parent); + rotateRight(n->parent); + } else { + rotateRight(n->parent); + rotateLeft(n->parent); + } + } + Splay(n); +} + +void SplayTree::Insert(int key) { + if (!root) { + root = new Node(key); + return; + } + + Node* current = root; + Node* parent = nullptr; + + while (current) { + parent = current; + if (key <= current->key) + current = current->left; + else + current = current->right; + } + + Node* new_n = new Node(key); + new_n->parent = parent; + + if (key <= parent->key) + parent->left = new_n; + else + parent->right = new_n; + + Splay(new_n); +} + +bool SplayTree::Find(int key) { + if (!root) return false; + + Node* current = root; + Node* last = nullptr; + + while (current) { + last = current; + if (key == current->key) { + Splay(current); + return true; + } else if (key < current->key) + current = current->left; + else + current = current->right; + } + if (last) Splay(last); + return false; +} + +void SplayTree::Remove(int key) { + if (Find(key)) { + Node* n = root; + + Node* left_tree = root->left; + Node* right_tree = root->right; + + if (!left_tree) { + root = right_tree; + if (right_tree) right_tree->parent = nullptr; + delete n; + return; + } + if (!right_tree) { + root = left_tree; + if (left_tree) left_tree->parent = nullptr; + delete n; + return; + } + + Node* current = right_tree; + Node* last = nullptr; + + while (current) { + last = current; + current = current->left; + } + + Splay(last); + + if (last->left) last->left->parent = nullptr; + last->left = nullptr; + + root = last; + last->left = left_tree; + left_tree->parent = last; + + delete n; + } +} \ No newline at end of file diff --git a/task_09/src/splay_tree.hpp b/task_09/src/splay_tree.hpp new file mode 100644 index 0000000..057fbc4 --- /dev/null +++ b/task_09/src/splay_tree.hpp @@ -0,0 +1,24 @@ +#pragma once + +struct Node { + Node(const int& key) + : key(key), left(nullptr), right(nullptr), parent(nullptr){}; + + Node* left; + Node* right; + Node* parent; + int key; +}; + +struct SplayTree { + Node* root{nullptr}; + + void Splay(Node* n); + void Insert(int key); // вставка ключа + bool Find(int key); // поиск ключа + void Remove(int key); // удаление ключа + + private: + void rotateRight(Node* n); + void rotateLeft(Node* n); +}; \ No newline at end of file