Вы должны убедиться, что length
равно как минимум 2, когда вы swap
, иначе вы будете менять номера за пределами. Ваши значения midl
и midh
в настоящее время неверны. Они относятся к begin
, поэтому вам нужно добавить к ним begin
. Однако вы можете добавить midl
к самому Array
и пропустить параметр begin
в своей функции, чтобы упростить интерфейс.
Я бы также заменил операции с плавающей запятой std::ceil
на целочисленную версию .
// A function to do integer division and return the ceil value
size_t DivCeil(size_t dividend, size_t divisor) {
return 1U + ((dividend - 1U) / divisor);
}
void FlipFlopSort(int* Array, size_t length) {
if(length > 2) {
// calculate midl & midh
size_t midl = DivCeil(length, 3U);
size_t midh = DivCeil(2U * length, 3U);
FlipFlopSort(Array, midh);
// add midl to Array and sub midl from length
FlipFlopSort(Array + midl, length - midl);
FlipFlopSort(Array, midh);
} else if(length == 2) {
if(Array[1] < Array[0]) {
// swap the values
std::swap(Array[0], Array[1]);
}
} // else length < 2 ... don't do anything
}
#include <iostream>
#include <vector>
int main() {
size_t n;
if(std::cin >> n) { // check that the user entered a number
// don't use VLA:s, use a std::vector instead
std::vector<int> Array(n);
for(size_t i = 0; i < Array.size(); ++i) {
std::cin >> Array[i];
}
FlipFlopSort(Array.data(), Array.size());
for(int value : Array) {
std::cout << value << '\n';
}
}
}
Если вы хотите, чтобы ваш алгоритм сортировки стал более универсальным c и использовался со стандартными контейнерами, вы можете заменить входные параметры итераторами.
Пример :
#include <algorithm> // std::iter_swap
#include <iterator> // std::distance, std::next
// A function to do integer division and return the ceil value
template<typename T>
T DivCeil(T dividend, T divisor) {
return 1 + ((dividend - 1) / divisor);
}
template<typename It>
void FlipFlopSort(It begin, It end) {
auto length = std::distance(begin, end); // iterator version of "length = end-begin"
static constexpr decltype(length) two = 2; // constant of the same type as length
static constexpr decltype(length) three = 3; // -"-
if(length > two) {
// calculate midl & midh iterators
auto midl = std::next(begin, DivCeil(length, three));
auto midh = std::next(begin, DivCeil(two * length, three));
FlipFlopSort(begin, midh);
FlipFlopSort(midl, end);
FlipFlopSort(begin, midh);
} else if(length == two) {
if(*std::next(begin) < *begin) {
// swap the values pointed at by the iterators
std::iter_swap(begin, std::next(begin));
}
} // else length == 1 or 0 ... don't do anything
}
Использование:
#include <iostream>
#include <vector>
int main() {
size_t n;
if(std::cin >> n) {
std::vector<int> Array(n);
for(size_t i = 0; i < Array.size(); ++i) {
std::cin >> Array[i];
}
FlipFlopSort(std::begin(Array), std::end(Array));
for(int value : Array) {
std::cout << value << '\n';
}
}
}