This commit is contained in:
2025-03-13 08:59:32 +03:00
parent 80dfb901a1
commit 55881d4062
9 changed files with 250 additions and 18 deletions

View File

@@ -4,4 +4,6 @@
1. Сортировка вставками 1. Сортировка вставками
2. Нахождение наибольшего общего делителя 2. Нахождение наибольшего общего делителя
3. Нахождение все простых множителей заданного числа. 3. Нахождение все простых множителей заданного числа. (в работе)
4. Сортировка слиянием. (в работе)
5. Возведение в степень. (в работе)

View File

@@ -1,27 +1,45 @@
#include <hack/logger/logger.hpp> #include <hack/logger/logger.hpp>
#include "base/insertion_sort.hpp" #include "base/insertion_sort.hpp"
#include "base/merge_sort.hpp"
#include "base/merge_sort.v2.hpp"
#include "numbers/gcd.hpp" #include "numbers/gcd.hpp"
#include "numbers/prime_factors.hpp" #include "numbers/prime_factors.hpp"
#include "numbers/pow.hpp"
auto main() -> int auto main() -> int
{ {
{
hack::log()(alg::pow(3.0, 2), alg::pow(3.0, 3));
return 1;
}
{
std::vector<int> v { 5, 4, 1, 5, 6 };
alg::insertion_sort(v);
hack::log()(v);
}
// std::vector<int> v { 2, 5, 4, 6, 1, 3 }; {
std::vector<int> v { 5, 4, 1, 5, 6 }; std::vector<int> v { 16, 7, 10, 1, 5, 11, 3, 8, 14, 4, 2, 12, 6, 13, 9, 15 };
algorithms::insertion_sort(v); alg_v2::merge_sort(v);
hack::log()(v); hack::log()(v);
}
// hack::log()(algorithms::gcd(4851, 3003)); {
// hack::log()(algorithms::gcd(64, 28)); hack::log()(alg::gcd(4851, 3003));
// hack::log()(alg::gcd(64, 28));
// hack::log()(algorithms::prime_factors_v1(127)); }
// hack::log()(algorithms::prime_factors_v1(128));
// hack::log()(algorithms::prime_factors_v1(130)); {
// hack::log()(alg::prime_factors_v1(127));
// hack::log()(algorithms::prime_factors_v2(127)); hack::log()(alg::prime_factors_v1(128));
// hack::log()(algorithms::prime_factors_v2(128)); hack::log()(alg::prime_factors_v1(130));
// hack::log()(algorithms::prime_factors_v2(130));
hack::log()(alg::prime_factors_v2(127));
hack::log()(alg::prime_factors_v2(128));
hack::log()(alg::prime_factors_v2(130));
}
} }

View File

@@ -5,7 +5,7 @@
// Сортировка вставкой // Сортировка вставкой
// Эффективна на мелких массивах. Сложнгость O(N^2) // Эффективна на мелких массивах. Сложнгость O(N^2)
namespace algorithms namespace alg
{ {
inline void insertion_sort(std::vector<int>& v) inline void insertion_sort(std::vector<int>& v)
{ {

38
src/base/merge_sort.hpp Normal file
View File

@@ -0,0 +1,38 @@
#pragma once
#include <vector>
#include <hack/logger/logger.hpp>
// Сортировка вставкой
// Эффективна на мелких массивах. Сложнгость O(N^2)
namespace alg
{
inline void merge(std::vector<int>& v, int left, int mid, int right, std::vector<int>& tmp)
{
for(int i = left, j = mid + 1; left <= right; ++left)
{
bool useRight = i > mid || (j <= right && tmp[j] < tmp[i]);
v[left] = tmp[(useRight ? j : i)++];
}
}
inline void merge_sort_helper(std::vector<int>& v, int left, int right, std::vector<int>& tmp)
{
if (left < right)
{
int mid = (left + right) / 2;
merge_sort_helper(tmp, left, mid, v);
merge_sort_helper(tmp, mid + 1, right, v);
merge(v, left, mid, right, tmp);
}
}
inline void merge_sort(std::vector<int>& v)
{
std::vector<int> tmp(v);
merge_sort_helper(v, 0, v.size() - 1, tmp);
}
}

View File

@@ -0,0 +1,84 @@
#pragma once
#include <vector>
#include <hack/logger/logger.hpp>
#include "insertion_sort.hpp"
// Сортировка вставкой
// Эффективна на мелких массивах. Сложнгость O(N^2)
namespace alg_v1
{
// Функция для слияния двух отсортированных половин массива
inline void merge(std::vector<int>& v, int start1, int end1, int start2, int end2)
{
auto fs = start1;
auto fe = end2;
int i = 1;
std::vector<int> tmp(v);
while (start1 <= end1 && (start2 <= end2))
{
if (v[start1] < v[start2])
{
tmp[i] = v[start1];
++start1;
}
else
{
tmp[i] = v[start2];
++start2;
}
++i;
}
if (start1 <= end1)
{
for (int j = start1; j < end1; ++j)
{
tmp[i] = v[j];
++i;
}
}
else
{
for (int j = start2; j < end2; ++j)
{
tmp[i] = v[j];
++i;
}
}
i = 1;
for (int j = fs; j < fe; ++j)
{
v[j] = tmp[i];
++i;
}
}
inline void merge_sort_helper(int i, std::vector<int>& v, int first, int last)
{
if (first < last)
{
// Находим среднюю точку
int mid = (first + last) / 2;
hack::log()(i, " | first =", first, ", last =", last, ", mid =", mid);
// Сортируем первую и вторую половины
merge_sort_helper(1, v, first, mid);
merge_sort_helper(2, v, mid + 1, last);
// Сливаем отсортированные половины
merge(v, first, mid, mid + 1, last);
}
}
inline void merge_sort(std::vector<int>& v)
{
merge_sort_helper(0, v, 0, v.size() - 1);
}
}

View File

@@ -0,0 +1,67 @@
#pragma once
#include <vector>
#include <hack/logger/logger.hpp>
#include "insertion_sort.hpp"
// Сортировка вставкой
// Эффективна на мелких массивах. Сложнгость O(N^2)
namespace alg_v2
{
inline void merge(std::vector<int>& v, int left, int mid, int right)
{
std::vector<int> l(v.begin() + left, v.begin() + mid + 1);
std::vector<int> r(v.begin() + mid + 1, v.begin() + right + 1);
int i = 0; // индекс для левой подсистемы
int j = 0; // индекс для правой подсистемы
int k = left; // индекс для A[p:r+1]
// Объединение двух отсортированных подсистем
while (i < l.size() && j < r.size())
{
if (l[i] <= r[j]) {
v[k] = l[i];
i++;
} else {
v[k] = r[j];
j++;
}
k++;
}
// Копирование оставшихся элементов левой подсистемы (если есть)
while (i < l.size())
{
v[k] = l[i];
i++;
k++;
}
// Копирование оставшихся элементов правой подсистемы (если есть)
while (j < r.size()) {
v[k] = r[j];
j++;
k++;
}
}
inline void merge_sort_helper(std::vector<int>& v, int left, int right)
{
if (left < right)
{
int mid = (left + right) / 2;
merge_sort_helper(v, left, mid);
merge_sort_helper(v, mid + 1, right);
merge(v, left, mid, right);
}
}
inline void merge_sort(std::vector<int>& v)
{
merge_sort_helper(v, 0, v.size() - 1);
}
}

View File

@@ -2,7 +2,7 @@
// Называется алгоритм Евклида // Называется алгоритм Евклида
// Находит наибольший общий делитель // Находит наибольший общий делитель
namespace algorithms namespace alg
{ {
inline int gcd(int a, int b) inline int gcd(int a, int b)
{ {

23
src/numbers/pow.hpp Normal file
View File

@@ -0,0 +1,23 @@
#pragma once
// Возведение в степень
namespace alg
{
inline int pow(double a, int n)
{
double result = 1.0;
bool is_negative = n < 0;
if (is_negative) n *= -1;
while (n > 0)
{
if (n & 1) result *= a;
a *= a;
n >>= 1;
}
return is_negative ? 1.0 / result : result;
}
}

View File

@@ -5,7 +5,7 @@
// Находит все простые множители заданного числа. // Находит все простые множители заданного числа.
// Простое число - это число > 1, которое делится на 1 и на само себя. // Простое число - это число > 1, которое делится на 1 и на само себя.
namespace algorithms namespace alg
{ {
inline std::vector<int> prime_factors_v1(int a) inline std::vector<int> prime_factors_v1(int a)
{ {