#pragma once #include #include #include #include #include #include #include #include #include #include std::vector generateJacobsthal(size_t n) { std::vector seq; if (n == 0) return seq; seq.push_back(0); if (n == 1) return seq; seq.push_back(1); size_t j0 = 0, j1 = 1; while (true) { size_t jn = j1 + 2 * j0; if (jn >= n) break; seq.push_back(jn); j0 = j1; j1 = jn; } return seq; } template struct Pair { T first; T second; }; template struct PairComp { bool operator()(const Pair &x, const Pair &y) const { return x.second < y.second; } }; template Container fordJohnsonSort(const Container &input) { typedef typename Container::value_type T; Container result; if (input.size() <= 1) return input; std::vector > pairs; size_t i = 0; for (; i + 1 < input.size(); i += 2) { T a = input[i]; T b = input[i+1]; if (a > b) std::swap(a, b); Pair p; p.first = a; p.second = b; pairs.push_back(p); } std::sort(pairs.begin(), pairs.end(), PairComp()); for (size_t k = 0; k < pairs.size(); ++k) result.push_back(pairs[k].second); std::vector order = generateJacobsthal(pairs.size()); std::vector inserted(pairs.size(), false); for (size_t idx = 0; idx < order.size(); ++idx) { size_t j = order[idx]; if (j < pairs.size() && !inserted[j]) { typename Container::iterator pos = std::lower_bound( result.begin(), result.end(), pairs[j].first); result.insert(pos, pairs[j].first); inserted[j] = true; } } for (size_t j = 0; j < pairs.size(); ++j) { if (!inserted[j]) { typename Container::iterator pos = std::lower_bound( result.begin(), result.end(), pairs[j].first); result.insert(pos, pairs[j].first); } } if (i < input.size()) { T leftover = input[i]; typename Container::iterator pos = std::lower_bound(result.begin(), result.end(), leftover); result.insert(pos, leftover); } return result; }