37#include <gtest/gtest.h>
81 for (
const int x :
xs)
86template <
class Compare>
90 std::vector<size_t> ref(values.size());
91 for (
size_t i = 0; i < ref.size(); ++i)
94 std::stable_sort(ref.begin(), ref.end(),
95 [&values, &
cmp](
const size_t i,
const size_t j)
97 return cmp(values[i], values[j]);
103template <
class Index>
105 const std::vector<size_t> &ref)
108 for (
size_t i = 0; i < ref.size(); ++i)
109 EXPECT_EQ(idx(i), ref[i]) <<
"position " << i;
112template <
class Compare>
115 constexpr size_t max_n = 7;
118 for (
size_t n = 0; n <=
max_n; ++n)
121 for (
size_t i = 0; i < n; ++i)
126 std::vector<int> values(n);
128 for (
size_t i = 0; i < n; ++i)
130 values[i] =
static_cast<int>(x %
alphabet);
174 while (
not h.is_empty())
207 for (
size_t i = 0; i < a.
size(); ++i)
286 int a[] = {3, 1, 2, 1, 0};
288 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
309 for (
size_t i = 1; i < a.size(); ++i)
317 for (
size_t i = 1; i < a.size(); ++i)
325 for (
size_t i = 1; i < a.size(); ++i)
333 for (
size_t i = 1; i < a.size(); ++i)
344 for (
size_t child = 2; child <= n; ++child)
346 size_t parent = child / 2;
347 if (a(parent - 1) > a(child - 1))
372 for (
int x : {5, 4, 3, 2, 1, 0})
384 for (
size_t i = 0; i < a.
size(); ++i)
391 const int pivot = a(p);
392 for (
long i = 0; i < p; ++i)
397 std::vector<int>
after;
399 for (
size_t i = 0; i < a.
size(); ++i)
400 after.push_back(a(i));
409 for (
int x : {4, 1, 3, 2, 0, 2})
414 for (
size_t i = 0; i < a.
size(); ++i)
421 const int pivot = a(p);
422 for (
long i = 0; i < p; ++i)
427 std::vector<int>
after;
429 for (
size_t i = 0; i < a.
size(); ++i)
430 after.push_back(a(i));
440 auto expected = std::vector<int>{4, 1, 3, 2, 0, 2};
449 for (
int x : {4, 1, 3, 2, 0, 2})
451 auto expected = std::vector<int>{4, 1, 3, 2, 0, 2};
470 int a[] = {4, 1, 3, 2, 0, 2};
484 int a[] = {0, 2, 4, 1, 3, 5};
486 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
500 int a[] = {5, 4, 3, 2, 1, 0, 0, 9};
502 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
537 delete_all_nodes(
h2);
552 for (
int x : {3, 1, 2, 0})
586 int a[] = {4, 1, 3, 2, 0, 2};
587 std::vector<int>
expected(std::begin(a), std::end(a));
627 int a[] = {5, 4, 3, 2, 1, 0, 0, 9};
628 mergesort(a, 0,
static_cast<int>((
sizeof(a) /
sizeof(a[0])) - 1));
629 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
634 int a[] = {5, 4, 3, 2, 1, 0, 0, 9};
635 quicksort(a, 0,
static_cast<int>((
sizeof(a) /
sizeof(a[0])) - 1));
636 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
641 int a[] = {5, 4, 3, 2, 1, 0, 0, 9};
642 quicksort_rec(a, 0,
static_cast<int>((
sizeof(a) /
sizeof(a[0])) - 1));
643 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
648 int a[] = {5, 4, 3, 2, 1, 0, 0, 9};
650 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
655 int a[] = {9, 1, 8, 2, 7, 3, 6, 4, 5, 0};
657 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
661 EXPECT_TRUE(std::is_sorted(std::begin(b), std::end(b)));
667 int a[] = {5, 4, 3, 2, 1, 0, 0, 9};
668 introsort(a, 0
L,
static_cast<long>((
sizeof(a) /
sizeof(a[0])) - 1));
669 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
674 int a[] = {9, 1, 8, 2, 7, 3, 6, 4, 5, 0};
676 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
681 int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
683 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a), std::greater<int>()));
690 for (
size_t i = 1; i < a.size(); ++i)
713 int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
715 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
720 int a[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
722 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
727 int a[] = {5, 5, 5, 5, 5, 5, 5, 5, 5, 5};
729 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
736 const size_t n = 10000;
737 std::vector<int> v(n);
738 for (
size_t i = 0; i < n; ++i)
739 v[i] =
static_cast<int>(n - i);
748 const size_t n = 5000;
751 for (
size_t i = 0; i < n; ++i)
752 a(i) =
static_cast<int>(n - i);
755 for (
size_t i = 1; i < n; ++i)
756 ASSERT_LE(a(i - 1), a(i)) <<
"Failed at index " << i;
762 int a[] = {9, 1, 8, 2, 7, 3, 6, 4, 5, 0};
764 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
769 int a[] = {9, 1, 8, 2, 7, 3, 6, 4, 5, 0};
781 int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
782 introsort(a, a + 9, std::greater<int>());
783 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a), std::greater<int>()));
807 for (
size_t i = 1; i < arr.
size(); ++i)
814 for (
int i = 1; i <= 10; ++i)
819 for (
size_t i = 1; i < arr.
size(); ++i)
841 const size_t n = 5000;
843 for (
size_t i = 0; i < n; ++i)
844 arr.
append(
static_cast<int>(n - i));
848 for (
size_t i = 1; i < n; ++i)
849 ASSERT_LE(arr(i - 1), arr(i)) <<
"Failed at index " << i;
856 for (
size_t i = 1; i < a.size(); ++i)
864 for (
size_t i = 1; i < a.size(); ++i)
879 for (
size_t i = 1; i < a.
size(); ++i)
887 for (
size_t i = 1; i < a.
size(); ++i)
895 for (
size_t i = 1; i < a.
size(); ++i)
970 delete_all_nodes(
out);
1031 delete_all_nodes(
h);
1043 int a[] = {4, 1, 3, 2, 0, 2};
1087 delete_all_nodes(
h);
1096 delete_all_nodes(
h);
1101 int a[] = {4, 1, 3, 2, 0, 2};
1152 delete_all_nodes(
h);
1159 delete_all_nodes(
h);
1166 delete_all_nodes(
h);
1173 delete_all_nodes(
h);
1188 delete_all_nodes(
h);
1258 static_assert(std::is_same_v<
decltype(idx),
Array<size_t>>);
1260 for (
size_t i = 1; i < idx.size(); ++i)
1266 for (
size_t i = 1; i <
ptrs.size(); ++i)
1273 for (
size_t i = 1; i <
cptrs.size(); ++i)
1279 std::vector<int> a = {3, 1, 2, 1, 0};
1283 static_assert(std::is_same_v<
decltype(idx),
Array<size_t>>);
1285 for (
size_t i = 1; i < idx.size(); ++i)
1295 static_assert(std::is_same_v<
decltype(idx),
Array<size_t>>);
1324 for (
size_t i = 0; i <
ptrs.size(); ++i)
1332 for (
size_t i = 0; i < 75; ++i)
1333 a(i) =
static_cast<int>((i * 17) % 5);
1339 for (
size_t i = 1; i <
ptrs.size(); ++i)
1344 <<
"equal-valued elements must keep their original relative order";
1351 for (
size_t i = 0; i < 75; ++i)
1352 a.push_back(
static_cast<int>((i * 17) % 5));
1356 static_assert(std::is_same_v<
decltype(idx),
Array<size_t>>);
1358 for (
size_t i = 1; i < idx.size(); ++i)
1361 if (a[idx(i - 1)] == a[idx(i)])
1378 std::vector<int> a = {2, 1, 2, 1, 2};
1382 static_assert(std::is_same_v<
decltype(idx),
Array<size_t>>);
1453 delete_all_nodes(
h);
1458 int a[] = {4, 1, 3, 2, 0, 2};
1465 idx =
random_search(d, 3, 0,
static_cast<long>(d.size() - 1));
1474 for (
int x : {4, 1, 3, 2, 0, 2})
1500 int b[] = {4, 1, 3};
1502 auto fn =
static_cast<const int & (*)(
int *,
const long,
const long,
const Cmp &)
>(
1522 delete_all_nodes(
h);
1546 int a[] = {0, 2, 4, 6};
1556 int a[] = {0, 2, 4, 6};
1570 int b[] = {4, 1, 3, 2, 0, 2};
1572 auto fn =
static_cast<const int & (*)(
int *,
const long,
const long,
const Cmp &)
>(
1583 for (
size_t i = 0; i < a.size(); ++i)
1612 for (
size_t i = 0; i < a.size(); ++i)
1629 for (
size_t i = 0; i < a.size(); ++i)
1643 for (
size_t i = 0; i < a.size(); ++i)
1664 for (
size_t i = 0; i < a.size(); ++i)
1678 for (
size_t i = 0; i < a.size(); ++i)
1692 for (
size_t i = 0; i < a.size(); ++i)
1708 for (
size_t i = 0; i < a.size(); ++i)
1725 sa[0] = 3; sa[1] = 0; sa[2] = 4; sa[3] = 1; sa[4] = 2;
1728 [](
size_t idx) ->
int {
return static_cast<int>(idx); });
1730 for (
size_t i = 0; i < 5; ++i)
1748 sa[0] = 0; sa[1] = 1; sa[2] = 2; sa[3] = 3;
1750 std::array<int, 4>
keys = {2, 1, 1, 0};
1752 [&](
size_t idx) ->
int {
return keys[idx]; });
1765 sa[0] = 0; sa[1] = 1; sa[2] = 2; sa[3] = 3;
1767 std::array<int, 4>
keys = {0, -1, 2, -2};
1769 [&](
size_t idx) ->
int {
return keys[idx]; });
1785 [](
size_t) ->
int {
return 0; });
1794 [](
size_t) ->
int {
return 0; });
1806 [](
size_t) ->
int {
return 0; }),
1819 [](
size_t idx) ->
int {
return idx == 0 ? 0 : 2; }),
1831 [](
size_t idx) ->
int {
return static_cast<int>(idx); }),
1842 for (
size_t i = 1; i < a.size(); ++i)
1849 for (
unsigned int x : {7u, 0u, 3u, 7u, 1u, 2u})
1863 int a[] = {4, 1, 3, 0, 2};
1865 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
1873 int a[] = {5, 1, 4, 2, 3, 0};
1875 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
1882 for (
size_t i = 1; i < a.size(); ++i)
1908 std::array<int, 6>
expected = {-1, -1, 0, 2, 3, 4};
1929 std::array<int, 6>
expected = {-2, 0, 1, 3, 7, 7};
1950 a(1) = std::numeric_limits<unsigned long long>::max();
1958 for (
size_t i = 1; i < a.
size(); ++i)
1969 for (
size_t i = 1; i < a.
size(); ++i)
1976 for (
int x : {9, 1, 8, 2, 7, 3, 6, 4, 5, 0})
1980 for (
size_t i = 1; i < a.
size(); ++i)
1986 int a[] = {9, 1, 8, 2, 7, 3, 6, 4, 5, 0};
1988 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
1993 int a[] = {9, 1, 8, 2, 7, 3, 6, 4, 5, 0};
1995 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
2009 std::array<int, 6>
expected = {-5, -1, 0, 2, 3, 3};
2030 std::array<int, 6>
expected = {-2, -2, 0, 1, 7, 10};
2050 a(0) = std::numeric_limits<int>::max();
2052 a(2) = std::numeric_limits<int>::min();
2054 a(4) = std::numeric_limits<int>::max();
2055 a(5) = std::numeric_limits<int>::min();
2059 EXPECT_EQ(a(0), std::numeric_limits<int>::min());
2060 EXPECT_EQ(a(1), std::numeric_limits<int>::min());
2061 EXPECT_EQ(a(4), std::numeric_limits<int>::max());
2062 EXPECT_EQ(a(5), std::numeric_limits<int>::max());
2063 for (
size_t i = 1; i < a.
size(); ++i)
2070 for (
unsigned int x : {std::numeric_limits<unsigned int>::max(),
2071 0u, 10u, 1u, 1024u, 10u})
2080 EXPECT_EQ(a(a.
size() - 1), std::numeric_limits<unsigned int>::max());
2081 for (
size_t i = 1; i < a.
size(); ++i)
2100 DynArray<int> v =
make_dynarray({9, 2, 4, 7, 3, 7, 10, 2, 7, 1, 8, 7, 7, 7, 7});
2101 std::vector<int>
expected = {9, 2, 4, 7, 3, 7, 10, 2, 7, 1, 8, 7, 7, 7, 7};
2104 for (
size_t i = 0; i < v.
size(); ++i)
2115 for (
int i = 0; i < 100; ++i)
2118 for (
size_t i = 0; i < v.
size(); i += 10)
2129 for (
int i = 0; i < 50; ++i)
2133 for (
int i = 49; i >= 0; --i)
2136 for (
size_t i = 0; i < v.
size(); i += 5)
2148 std::mt19937
gen(42);
2151 const size_t N = std::uniform_int_distribution<size_t>(1, 200)(
gen);
2154 for (
size_t i = 0; i <
N; ++i)
2156 int val = std::uniform_int_distribution<int>(-1000, 1000)(
gen);
2162 const long k = std::uniform_int_distribution<long>(0,
static_cast<long>(
N) - 1)(
gen);
2175 constexpr size_t N = 500;
2178 std::mt19937
gen(42);
2179 std::uniform_real_distribution<float> dist(0.0f, 1.0f);
2180 for (
size_t i = 0; i <
N; ++i)
2184 for (
size_t i = 1; i <
N; ++i)
2190 constexpr size_t N = 300;
2193 std::mt19937
gen(123);
2194 std::uniform_real_distribution<float> dist(-100.0f, 100.0f);
2195 for (
size_t i = 0; i <
N; ++i)
2199 for (
size_t i = 1; i <
N; ++i)
2205 constexpr size_t N = 200;
2208 std::mt19937
gen(77);
2209 std::uniform_real_distribution<double> dist(-50.0, 50.0);
2210 for (
size_t i = 0; i <
N; ++i)
2214 for (
size_t i = 1; i <
N; ++i)
2220 constexpr size_t N = 100;
2223 std::mt19937
gen(99);
2224 std::uniform_real_distribution<double> dist(-10.0, 10.0);
2225 for (
size_t i = 0; i <
N; ++i)
2229 for (
size_t i = 1; i <
N; ++i)
2230 ASSERT_GE(a(i - 1), a(i)) <<
"Failed at index " << i <<
" values: " << a(i-1) <<
", " << a(i);
2235 int a[] = {95, 23, 67, 12, 45, 78, 34, 56, 89, 1};
2236 const size_t n =
sizeof(a) /
sizeof(a[0]);
2237 const size_t num_buckets = 10;
2239 auto key = [](
const int & val) ->
size_t
2241 return static_cast<size_t>(val / 10);
2245 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
2269 const size_t n =
sizeof(a) /
sizeof(a[0]);
2270 const size_t num_buckets = 4;
2273 return static_cast<size_t>(x.value / 2);
2277 return lhs.value < rhs.value;
2282 for (
size_t i = 1; i < n; ++i)
2288 constexpr size_t N = 100;
2291 std::mt19937
gen(55);
2292 std::uniform_real_distribution<double> dist(0.0, 1.0);
2293 for (
size_t i = 0; i <
N; ++i)
2297 for (
size_t i = 1; i <
N; ++i)
2304 std::mt19937
gen(99);
2305 std::uniform_real_distribution<double> dist(-10.0, 10.0);
2306 for (
size_t i = 0; i < 50; ++i)
2310 for (
size_t i = 1; i < a.
size(); ++i)
2316 double a[] = {3.5, 1.2, 4.8, 0.3, 2.7, 1.9, 4.1, 0.1};
2318 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
2332 double prev = -std::numeric_limits<double>::infinity();
2336 prev = it.get_curr();
2356 constexpr size_t N = 50;
2359 for (
size_t i = 0; i <
N; ++i)
2363 for (
size_t i = 0; i <
N; ++i)
2369 constexpr size_t N = 100;
2372 for (
size_t i = 0; i <
N; ++i)
2373 a(i) =
static_cast<double>(
N - i);
2376 for (
size_t i = 1; i <
N; ++i)
2395 Record data[] = {{0, 0}, {2, 1}, {0, 2}, {1, 3}, {2, 4}, {1, 5}};
2396 const size_t n =
sizeof(data) /
sizeof(data[0]);
2397 const size_t num_buckets = 3;
2399 auto key = [](
const Record &
r) ->
size_t {
return r.group; };
2400 auto cmp = [](
const Record & a,
const Record & b) {
return a.group < b.group; };
2405 for (
size_t i = 1; i < n; ++i)
2423 int a[] = {3, 1, 2};
2425 const size_t num_buckets = 0;
2426 auto key = [](
const int &) ->
size_t {
return 0; };
2438 constexpr size_t N = 200;
2441 for (
size_t i = 0; i <
N; ++i)
2442 a(i) =
static_cast<int>(i);
2445 for (
size_t i = 1; i <
N; ++i)
2451 constexpr size_t N = 200;
2454 for (
size_t i = 0; i <
N; ++i)
2455 a(i) =
static_cast<int>(
N - i);
2458 for (
size_t i = 1; i <
N; ++i)
2464 int a[] = {5, 3, 8, 1, 9, 2, 7, 4, 6, 0};
2465 timsort(
static_cast<int*
>(a),
size_t{10});
2466 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
2471 constexpr size_t N = 10000;
2474 std::mt19937
gen(42);
2475 std::uniform_int_distribution<int> dist(-1000000, 1000000);
2476 for (
size_t i = 0; i <
N; ++i)
2480 for (
size_t i = 1; i <
N; ++i)
2486 if (
not std::getenv(
"ENABLE_PERF_TESTS"))
2487 GTEST_SKIP() <<
"Skipping perf test (set ENABLE_PERF_TESTS to enable)";
2489 constexpr size_t N = 100000;
2492 std::mt19937
gen(42);
2493 std::uniform_int_distribution<int> dist(-1000000, 1000000);
2494 for (
size_t i = 0; i <
N; ++i)
2497 auto start = std::chrono::steady_clock::now();
2499 auto end = std::chrono::steady_clock::now();
2501 auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
2504 if (
const char *
env_ms = std::getenv(
"TIMSORT_MAX_MS"))
2505 max_ms = std::atol(
env_ms);
2507 EXPECT_LE(duration, max_ms) <<
"Timsort performance regression detected";
2509 for (
size_t i = 1; i <
N; ++i)
2515 constexpr size_t N = 100;
2518 for (
size_t i = 0; i <
N; ++i)
2522 for (
size_t i = 0; i <
N; ++i)
2528 constexpr size_t N = 200;
2532 for (
size_t i = 0; i <
N / 2; ++i)
2533 a(i) =
static_cast<int>(i * 2);
2535 for (
size_t i =
N / 2; i <
N; ++i)
2536 a(i) =
static_cast<int>((i -
N / 2) * 2 + 1);
2539 for (
size_t i = 1; i <
N; ++i)
2545 constexpr size_t N = 50;
2548 std::mt19937
gen(99);
2549 for (
size_t i = 0; i <
N; ++i)
2550 a(i) =
static_cast<int>(
gen() % 1000);
2553 for (
size_t i = 1; i <
N; ++i)
2561 for (
size_t i = 1; i < a.
size(); ++i)
2568 for (
int x : {9, 1, 8, 2, 7, 3, 6, 4, 5, 0})
2572 for (
size_t i = 1; i < a.
size(); ++i)
2578 int a[] = {5, 3, 8, 1, 9, 2, 7, 4, 6, 0};
2580 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
2588 int prev = std::numeric_limits<int>::min();
2592 prev = it.get_curr();
2625 {3, 0}, {1, 1}, {4, 2}, {1, 3}, {5, 4},
2626 {9, 5}, {2, 6}, {6, 7}, {5, 8}, {3, 9}
2628 const size_t n =
sizeof(data) /
sizeof(data[0]);
2630 auto cmp = [](
const Record & a,
const Record & b) {
return a.key < b.key; };
2634 for (
size_t i = 1; i < n; ++i)
2635 ASSERT_LE(data[i - 1].key, data[i].key);
2638 for (
size_t i = 1; i < n; ++i)
2639 if (data[i - 1].key == data[i].key)
2641 <<
"Stability violated at index " << i;
2664 constexpr size_t N = 500;
2667 for (
size_t i = 0; i <
N; ++i)
2668 a(i) =
static_cast<int>(i);
2671 std::mt19937
gen(12);
2672 for (
int k = 0;
k < 10; ++
k)
2674 size_t i =
gen() %
N;
2675 size_t j =
gen() %
N;
2676 std::swap(a(i), a(j));
2680 for (
size_t i = 1; i <
N; ++i)
2686 int a[] = {9, 5, 3, 8, 1, 7, 2, 6, 4, 0};
2691 for (
int i = 3; i <= 7; ++i)
2714 for (
size_t n = 64; n < 10000; ++n)
static DynArray< int > make_dynarray(std::initializer_list< int > vals)
bool operator<(const Time &l, const Time &r)
static bool is_min_heap(const std::vector< int > &v)
size_t size_t int32_t value
size_t size_t int32_t * out
Simple dynamic array with automatic resizing and functional operations.
static Array create(size_t n)
Create an array with n logical elements.
constexpr size_t size() const noexcept
Return the number of elements stored in the stack.
constexpr bool is_empty() const noexcept
Checks if the container is empty.
T & append(const T &data)
Append a copy of data
Helper class to compare nodes of a linked list.
bool has_curr() const noexcept
Return true if the iterator has current item.
Doubly linked circular list node.
Iterator on a list of Dnode objects.
Node belonging to a double circular linked list with header node.
Dnode< T > * remove_first_ne() noexcept
Remove the first node and return its address.
size_t size() const noexcept
Return the current dimension of array.
T & append()
Allocate a new entry to the end of array.
bool is_empty() const noexcept
Return true if the array is empty.
void reserve(const size_t l, const size_t r)
Allocate a range of entries.
Dynamic doubly linked list with O(1) size and bidirectional access.
Iterator on the items of list.
Doubly-linked list (defined in tpl_dynList.H).
T & append(const T &item)
T & get_last() const
Return the last item of the list.
T & get_first() const
Return the first item of the list.
bool has_curr() const noexcept
Single linked list of nodes.
constexpr bool is_empty() const noexcept
size_t size() const noexcept
Count the number of elements of the list.
Comparator wrapper that inverts the comparison order.
Link of a single linked list non-circular and without header node.
constexpr bool is_empty() const noexcept
Return true if this is empty.
Slinknc * remove_next() noexcept
void insert(Slinknc *p) noexcept
insert(p) inserts the node pointed by p after this.
Minimal std::expected-style result type for C++20.
int cmp(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
constexpr size_t compute_minrun(size_t n) noexcept
Compute the minimum run length for timsort.
Main namespace for Aleph-w library functions.
Array< const T * > build_index_ptr(const C< T > &a, const Compare &cmp=Compare())
Build an index array of pointers for indirect sorting (const version).
DynList< size_t > binary_search_dup(const C< T > &a, const T &x, const Compare &cmp=Compare())
Binary search for all occurrences of a value.
and std::convertible_to< std::invoke_result_t< const KeyFn &, size_t >, int > void counting_sort_indices(Array< size_t > &sa, Array< size_t > &tmp, const size_t n, const int min_key, const int max_key, const KeyFn &key_of)
Stable counting sort on an index array by integer keys.
long search_min(T *a, const long l, const long r, const Compare &cmp=Compare())
Returns the smallest element of the array a between l and r.
bool is_sorted(const Container< T > &cont, const Compare &cmp=Compare())
Check if a container is sorted in ascending order.
Array< const T * > stable_build_index_ptr(const C< T > &a, const Compare &cmp=Compare())
Build a stable index array of pointers for indirect sorting (const version).
std::pair< bool, size_t > search_inversion(const Container< T > &cont, const Compare &cmp=Compare())
Find the first inversion in a container.
void heapsort(T *array, const size_t n, const Compare &cmp=Compare())
Sort an array using the heapsort algorithm.
Dnode< T > * dlink_random_search(Dlink &list, const T &x, const Compare &cmp=Compare())
Random search for an element in a dlink list.
Array< size_t > stable_build_index(const C &a, const Compare &cmp=Compare())
Build a stable index array for indirect sorting.
void quicksort_no_tail(T *a, long l, long r, const Compare &cmp=Compare())
Quicksort implementation with tail-recursion optimization.
long random_search(T *a, const T &x, const long l, const long r, const Compare &cmp=Compare())
Random search for an element in an array.
void insertion_sort(T *a, const long l, const long r, const Compare &cmp=Compare()) noexcept(noexcept(cmp(std::declval< T & >(), std::declval< T & >())) and std::is_nothrow_move_constructible_v< T > and std::is_nothrow_move_assignable_v< T >)
Sort an array using insertion sort.
const int Not_Found
Return value for search functions when element is not found.
void counting_sort(DynArray< T > &a)
Stable counting sort for integral DynArray values.
std::pair< bool, size_t > test_sorted(const Container< T > &cont, const Compare &cmp=Compare())
Test if a container is sorted, returning the inversion position.
long search_max(T *a, const long l, const long r, const Compare &cmp=Compare())
Returns the maximum element of the array a between l and r.
void timsort(T *a, const size_t n, const Compare &cmp=Compare())
Timsort — adaptive, stable, natural merge sort.
void mergeinsertsort(Tlist< T > &list, const Compare &cmp=Compare(), const size_t lsz=Aleph::Insertion_Threshold)
Sort a list by mergesort combined with the insert method.
void insert_sorted(Dlink &list, Dlink *p, const Compare &cmp)
Inserts a node orderly into a doubly linked list.
Dlink * dlink_random_select(Dlink &list, const size_t i, const Compare &cmp=Compare())
Random selection of the ith element from a list based on Dlink.
Itor2 copy(Itor1 sourceBeg, const Itor1 &sourceEnd, Itor2 destBeg)
Copy elements from one range to another.
T * bsearch(C< T > &a, const T &x, const Compare &cmp=Compare())
Search for a value in a sorted container returning a pointer.
Array< size_t > build_index(const C &a, const Compare &cmp=Compare())
Build an index array for indirect sorting.
std::string code(Node *root)
Compute a string with the Lukasiewicz`s word of a tree.
const T & random_select(DynArray< T > &a, const long i, const Compare &cmp=Compare())
Select the i-th smallest element in a DynArray.
void bucket_sort(T *a, const size_t n, const size_t num_buckets, const BucketKey &bucket_key, const Compare &cmp=Compare())
Bucket sort with user-supplied bucket mapping.
static long back_index(const long i) noexcept
Convert a 1-based heap index to a 0-based array index.
void bubble_sort(DynArray< T > &a, const Compare &cmp=Compare())
Sort a dynamic array using bubble sort.
void quicksort(T *a, const long l, const long r, const Compare &cmp=Compare())
Sort an array using iterative quicksort with optimizations.
void radix_sort(DynArray< T > &a)
LSD radix sort for integral DynArray values.
void mergesort(T *a, const long l, const long r, Array< T > &buf, Compare cmp)
Sort an array using merge sort with a reusable buffer.
void shellsort(DynArray< T > &a, const Compare &cmp=Compare())
Sort a dynamic array using Shell sort.
Itor3 merge(Itor1 source1Beg, Itor1 source1End, Itor2 source2Beg, Itor2 source2End, Itor3 destBeg)
Merge two sorted ranges.
void quicksort_rec_min(T *a, const long l, const long r, const Compare &cmp=Compare())
Sorts an array according to the quicksort method with minimum space consumption.
long sequential_search(T *a, const T &x, const long l, const long r, Equal eq=Equal())
Linear search for an element in an array.
Link * search_extreme(const Link &list, const Compare &cmp)
Find the extreme (minimum or maximum) element in a linked list.
bool binary_search(Itor beg, Itor end, const T &value)
Binary search for a value.
static const T & __random_select(T *a, const long i, long l, long r, const Compare &cmp)
void quicksort_rec(T *a, const long l, const long r, const Compare &cmp=Compare())
Recursively sort an array using quicksort.
DynList< long > binindex_dup(const C< T > &a, const T &x, const Compare &cmp=Compare())
Returns the indices of all occurrences of a value in a sorted container.
bool is_inversely_sorted(const Container< T > &cont, const Compare &cmp=Compare())
Check if a container is sorted in descending order.
DynList< const T * > bsearch_dup(const C< T > &a, const T &x, const Compare &cmp=Compare())
Search for all occurrences of a value returning pointers (const version).
void selection_sort(T *a, const size_t n, const Compare &cmp=Compare()) noexcept(noexcept(cmp(a[0], a[0])) &&std::is_nothrow_swappable_v< T >)
Sort an array using the selection sort algorithm.
void introsort(T *a, const long l, const long r, const Compare &cmp=Compare())
Sort an array using introsort (introspective sort).
long binindex(const C< T > &a, const T &x, const Compare &cmp=Compare())
Returns the index where a value appears (or should be inserted) in a sorted container.
void quicksort_insertion(T *a, const long l, const long r, const Compare &cmp=Compare())
Sorts an array by the improved quicksort method.
long binary_search_rec(T *a, const T &x, const long l, const long r, const Compare &cmp=Compare())
Recursive binary search on an ordered array.
void merge_lists(Tlist &l1, Tlist &l2, Tlist &result, const Compare &cmp=Compare())
Merge two sorted lists into a single sorted list.
void push2(Stack &stack, const A &a, const B &b)
Push two values onto a stack.
void quicksort_op(C< T > &a, const Compare &cmp=Compare(), const size_t threshold=Quicksort_Threshold)
Optimized quicksort for containers using operator().
Comparator specialization for Dnode objects.
Dynamic array container with automatic resizing.
Doubly linked list node with typed data.
Lazy and scalable dynamic array implementation.
Dynamic doubly linked list implementation.
Alias for htlist.H (DynList implementation).
Comprehensive sorting algorithms and search utilities for Aleph-w.