42_CPP09/ex02/src/PmergeMe.hpp

79 lines
1.8 KiB
C++

#pragma once
#include <algorithm>
#include <cstddef>
#include <iostream>
#include <utility>
#include <vector>
void sort_pair(std::pair<int, int>* pairs, size_t len);
void sort_pairs(std::pair<int, int>* pairs, size_t len);
template <typename T>
std::pair<int, int>* create_pairs(const T& array, size_t len)
{
std::pair<int, int>* pairs = new std::pair<int, int>[len];
for (size_t i = 0; i < len; i++)
{
pairs[i].second = array[i * 2];
if (array.size() > i * 2 + 1)
pairs[i].first = array[i * 2 + 1];
}
if (len % 2)
pairs[len - 1].first = pairs[len - 1].second;
return pairs;
}
template <typename T>
size_t binary_search(const T& array, size_t start, size_t end, int value) {
if (array[end] < value)
return end;
while (true)
{
int mid = start + ((end - start) / 2);
int min_value = array[mid];
if (min_value == value || end - start <= 1)
{
if (min_value < value)
return mid + 1;
return mid;
}
else if (min_value < value)
start = mid;
else if (min_value > value)
end = mid;
}
}
template <typename T>
void insert_sort(const std::pair<int, int>* pairs, size_t len, T& array)
{
for (size_t i = 1; i < len; i++)
{
array.push_back(pairs[i].first);
if (pairs[i].first == pairs[i].second)
continue;
size_t index = binary_search(array, 0, array.size() - 1, pairs[i].second);
array.insert(array.begin() + index, pairs[i].second);
}
}
template <typename T>
void PmergeMe(T& array)
{
if (array.size() < 2)
return;
std::size_t len = array.size() / 2 + array.size() % 2;
std::pair<int, int>* pairs = create_pairs(array, len);
sort_pair(pairs, len);
sort_pairs(pairs, len);
array.clear();
array.push_back(pairs[0].second);
if (pairs[0].second != pairs[0].first)
array.push_back(pairs[0].first);
insert_sort(pairs, len, array);
delete[] pairs;
}