37#include <gtest/gtest.h>
80 for (
const int x :
xs)
118 while (
not h.is_empty())
151 for (
size_t i = 0; i < a.
size(); ++i)
230 int a[] = {3, 1, 2, 1, 0};
232 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
253 for (
size_t i = 1; i < a.size(); ++i)
261 for (
size_t i = 1; i < a.size(); ++i)
269 for (
size_t i = 1; i < a.size(); ++i)
277 for (
size_t i = 1; i < a.size(); ++i)
288 for (
size_t child = 2; child <= n; ++child)
290 size_t parent = child / 2;
291 if (a(parent - 1) > a(child - 1))
316 for (
int x : {5, 4, 3, 2, 1, 0})
328 for (
size_t i = 0; i < a.
size(); ++i)
335 const int pivot = a(p);
336 for (
long i = 0; i < p; ++i)
341 std::vector<int>
after;
343 for (
size_t i = 0; i < a.
size(); ++i)
344 after.push_back(a(i));
353 for (
int x : {4, 1, 3, 2, 0, 2})
358 for (
size_t i = 0; i < a.
size(); ++i)
365 const int pivot = a(p);
366 for (
long i = 0; i < p; ++i)
371 std::vector<int>
after;
373 for (
size_t i = 0; i < a.
size(); ++i)
374 after.push_back(a(i));
384 auto expected = std::vector<int>{4, 1, 3, 2, 0, 2};
393 for (
int x : {4, 1, 3, 2, 0, 2})
395 auto expected = std::vector<int>{4, 1, 3, 2, 0, 2};
414 int a[] = {4, 1, 3, 2, 0, 2};
428 int a[] = {0, 2, 4, 1, 3, 5};
430 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
444 int a[] = {5, 4, 3, 2, 1, 0, 0, 9};
446 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
481 delete_all_nodes(
h2);
496 for (
int x : {3, 1, 2, 0})
530 int a[] = {4, 1, 3, 2, 0, 2};
531 std::vector<int>
expected(std::begin(a), std::end(a));
571 int a[] = {5, 4, 3, 2, 1, 0, 0, 9};
572 mergesort(a, 0,
static_cast<int>((
sizeof(a) /
sizeof(a[0])) - 1));
573 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
578 int a[] = {5, 4, 3, 2, 1, 0, 0, 9};
579 quicksort(a, 0,
static_cast<int>((
sizeof(a) /
sizeof(a[0])) - 1));
580 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
585 int a[] = {5, 4, 3, 2, 1, 0, 0, 9};
586 quicksort_rec(a, 0,
static_cast<int>((
sizeof(a) /
sizeof(a[0])) - 1));
587 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
592 int a[] = {5, 4, 3, 2, 1, 0, 0, 9};
594 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
599 int a[] = {9, 1, 8, 2, 7, 3, 6, 4, 5, 0};
601 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
605 EXPECT_TRUE(std::is_sorted(std::begin(b), std::end(b)));
611 int a[] = {5, 4, 3, 2, 1, 0, 0, 9};
612 introsort(a, 0
L,
static_cast<long>((
sizeof(a) /
sizeof(a[0])) - 1));
613 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
618 int a[] = {9, 1, 8, 2, 7, 3, 6, 4, 5, 0};
620 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
625 int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
627 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a), std::greater<int>()));
634 for (
size_t i = 1; i < a.size(); ++i)
657 int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
659 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
664 int a[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
666 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
671 int a[] = {5, 5, 5, 5, 5, 5, 5, 5, 5, 5};
673 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
680 const size_t n = 10000;
681 std::vector<int> v(n);
682 for (
size_t i = 0; i < n; ++i)
683 v[i] =
static_cast<int>(n - i);
692 const size_t n = 5000;
695 for (
size_t i = 0; i < n; ++i)
696 a(i) =
static_cast<int>(n - i);
699 for (
size_t i = 1; i < n; ++i)
700 ASSERT_LE(a(i - 1), a(i)) <<
"Failed at index " << i;
706 int a[] = {9, 1, 8, 2, 7, 3, 6, 4, 5, 0};
708 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
713 int a[] = {9, 1, 8, 2, 7, 3, 6, 4, 5, 0};
725 int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
726 introsort(a, a + 9, std::greater<int>());
727 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a), std::greater<int>()));
751 for (
size_t i = 1; i < arr.
size(); ++i)
758 for (
int i = 1; i <= 10; ++i)
763 for (
size_t i = 1; i < arr.
size(); ++i)
785 const size_t n = 5000;
787 for (
size_t i = 0; i < n; ++i)
788 arr.
append(
static_cast<int>(n - i));
792 for (
size_t i = 1; i < n; ++i)
793 ASSERT_LE(arr(i - 1), arr(i)) <<
"Failed at index " << i;
800 for (
size_t i = 1; i < a.size(); ++i)
808 for (
size_t i = 1; i < a.size(); ++i)
823 for (
size_t i = 1; i < a.
size(); ++i)
831 for (
size_t i = 1; i < a.
size(); ++i)
839 for (
size_t i = 1; i < a.
size(); ++i)
914 delete_all_nodes(
out);
987 int a[] = {4, 1, 3, 2, 0, 2};
1031 delete_all_nodes(
h);
1040 delete_all_nodes(
h);
1045 int a[] = {4, 1, 3, 2, 0, 2};
1096 delete_all_nodes(
h);
1103 delete_all_nodes(
h);
1110 delete_all_nodes(
h);
1117 delete_all_nodes(
h);
1132 delete_all_nodes(
h);
1202 for (
size_t i = 1; i < idx.size(); ++i)
1207 for (
size_t i = 1; i <
ptrs.size(); ++i)
1273 delete_all_nodes(
h);
1278 int a[] = {4, 1, 3, 2, 0, 2};
1285 idx =
random_search(d, 3, 0,
static_cast<long>(d.size() - 1));
1294 for (
int x : {4, 1, 3, 2, 0, 2})
1320 int b[] = {4, 1, 3};
1322 auto fn =
static_cast<const int & (*)(
int *,
const long,
const long,
const Cmp &)
>(
1342 delete_all_nodes(
h);
1366 int a[] = {0, 2, 4, 6};
1376 int a[] = {0, 2, 4, 6};
1390 int b[] = {4, 1, 3, 2, 0, 2};
1392 auto fn =
static_cast<const int & (*)(
int *,
const long,
const long,
const Cmp &)
>(
1403 for (
size_t i = 0; i < a.size(); ++i)
1432 for (
size_t i = 0; i < a.size(); ++i)
1449 for (
size_t i = 0; i < a.size(); ++i)
1463 for (
size_t i = 0; i < a.size(); ++i)
1484 for (
size_t i = 0; i < a.size(); ++i)
1498 for (
size_t i = 0; i < a.size(); ++i)
1512 for (
size_t i = 0; i < a.size(); ++i)
1528 for (
size_t i = 0; i < a.size(); ++i)
1545 sa[0] = 3; sa[1] = 0; sa[2] = 4; sa[3] = 1; sa[4] = 2;
1548 [](
size_t idx) ->
int {
return static_cast<int>(idx); });
1550 for (
size_t i = 0; i < 5; ++i)
1568 sa[0] = 0; sa[1] = 1; sa[2] = 2; sa[3] = 3;
1570 std::array<int, 4>
keys = {2, 1, 1, 0};
1572 [&](
size_t idx) ->
int {
return keys[idx]; });
1585 sa[0] = 0; sa[1] = 1; sa[2] = 2; sa[3] = 3;
1587 std::array<int, 4>
keys = {0, -1, 2, -2};
1589 [&](
size_t idx) ->
int {
return keys[idx]; });
1605 [](
size_t) ->
int {
return 0; });
1614 [](
size_t) ->
int {
return 0; });
1626 [](
size_t) ->
int {
return 0; }),
1639 [](
size_t idx) ->
int {
return idx == 0 ? 0 : 2; }),
1651 [](
size_t idx) ->
int {
return static_cast<int>(idx); }),
1662 for (
size_t i = 1; i < a.size(); ++i)
1669 for (
unsigned int x : {7u, 0u, 3u, 7u, 1u, 2u})
1683 int a[] = {4, 1, 3, 0, 2};
1685 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
1693 int a[] = {5, 1, 4, 2, 3, 0};
1695 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
1702 for (
size_t i = 1; i < a.size(); ++i)
1728 std::array<int, 6>
expected = {-1, -1, 0, 2, 3, 4};
1749 std::array<int, 6>
expected = {-2, 0, 1, 3, 7, 7};
1770 a(1) = std::numeric_limits<unsigned long long>::max();
1778 for (
size_t i = 1; i < a.
size(); ++i)
1789 for (
size_t i = 1; i < a.
size(); ++i)
1796 for (
int x : {9, 1, 8, 2, 7, 3, 6, 4, 5, 0})
1800 for (
size_t i = 1; i < a.
size(); ++i)
1806 int a[] = {9, 1, 8, 2, 7, 3, 6, 4, 5, 0};
1808 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
1813 int a[] = {9, 1, 8, 2, 7, 3, 6, 4, 5, 0};
1815 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
1829 std::array<int, 6>
expected = {-5, -1, 0, 2, 3, 3};
1850 std::array<int, 6>
expected = {-2, -2, 0, 1, 7, 10};
1870 a(0) = std::numeric_limits<int>::max();
1872 a(2) = std::numeric_limits<int>::min();
1874 a(4) = std::numeric_limits<int>::max();
1875 a(5) = std::numeric_limits<int>::min();
1879 EXPECT_EQ(a(0), std::numeric_limits<int>::min());
1880 EXPECT_EQ(a(1), std::numeric_limits<int>::min());
1881 EXPECT_EQ(a(4), std::numeric_limits<int>::max());
1882 EXPECT_EQ(a(5), std::numeric_limits<int>::max());
1883 for (
size_t i = 1; i < a.
size(); ++i)
1890 for (
unsigned int x : {std::numeric_limits<unsigned int>::max(),
1891 0u, 10u, 1u, 1024u, 10u})
1900 EXPECT_EQ(a(a.
size() - 1), std::numeric_limits<unsigned int>::max());
1901 for (
size_t i = 1; i < a.
size(); ++i)
1920 DynArray<int> v =
make_dynarray({9, 2, 4, 7, 3, 7, 10, 2, 7, 1, 8, 7, 7, 7, 7});
1921 std::vector<int>
expected = {9, 2, 4, 7, 3, 7, 10, 2, 7, 1, 8, 7, 7, 7, 7};
1924 for (
size_t i = 0; i < v.
size(); ++i)
1935 for (
int i = 0; i < 100; ++i)
1938 for (
size_t i = 0; i < v.
size(); i += 10)
1949 for (
int i = 0; i < 50; ++i)
1953 for (
int i = 49; i >= 0; --i)
1956 for (
size_t i = 0; i < v.
size(); i += 5)
1968 std::mt19937
gen(42);
1971 const size_t N = std::uniform_int_distribution<size_t>(1, 200)(
gen);
1974 for (
size_t i = 0; i <
N; ++i)
1976 int val = std::uniform_int_distribution<int>(-1000, 1000)(
gen);
1982 const long k = std::uniform_int_distribution<long>(0,
static_cast<long>(
N) - 1)(
gen);
1995 constexpr size_t N = 500;
1998 std::mt19937
gen(42);
1999 std::uniform_real_distribution<float> dist(0.0f, 1.0f);
2000 for (
size_t i = 0; i <
N; ++i)
2004 for (
size_t i = 1; i <
N; ++i)
2010 constexpr size_t N = 300;
2013 std::mt19937
gen(123);
2014 std::uniform_real_distribution<float> dist(-100.0f, 100.0f);
2015 for (
size_t i = 0; i <
N; ++i)
2019 for (
size_t i = 1; i <
N; ++i)
2025 constexpr size_t N = 200;
2028 std::mt19937
gen(77);
2029 std::uniform_real_distribution<double> dist(-50.0, 50.0);
2030 for (
size_t i = 0; i <
N; ++i)
2034 for (
size_t i = 1; i <
N; ++i)
2040 constexpr size_t N = 100;
2043 std::mt19937
gen(99);
2044 std::uniform_real_distribution<double> dist(-10.0, 10.0);
2045 for (
size_t i = 0; i <
N; ++i)
2049 for (
size_t i = 1; i <
N; ++i)
2050 ASSERT_GE(a(i - 1), a(i)) <<
"Failed at index " << i <<
" values: " << a(i-1) <<
", " << a(i);
2055 int a[] = {95, 23, 67, 12, 45, 78, 34, 56, 89, 1};
2056 const size_t n =
sizeof(a) /
sizeof(a[0]);
2057 const size_t num_buckets = 10;
2059 auto key = [](
const int & val) ->
size_t
2061 return static_cast<size_t>(val / 10);
2065 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
2089 const size_t n =
sizeof(a) /
sizeof(a[0]);
2090 const size_t num_buckets = 4;
2093 return static_cast<size_t>(x.value / 2);
2097 return lhs.value <
rhs.value;
2102 for (
size_t i = 1; i < n; ++i)
2108 constexpr size_t N = 100;
2111 std::mt19937
gen(55);
2112 std::uniform_real_distribution<double> dist(0.0, 1.0);
2113 for (
size_t i = 0; i <
N; ++i)
2117 for (
size_t i = 1; i <
N; ++i)
2124 std::mt19937
gen(99);
2125 std::uniform_real_distribution<double> dist(-10.0, 10.0);
2126 for (
size_t i = 0; i < 50; ++i)
2130 for (
size_t i = 1; i < a.
size(); ++i)
2136 double a[] = {3.5, 1.2, 4.8, 0.3, 2.7, 1.9, 4.1, 0.1};
2138 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
2152 double prev = -std::numeric_limits<double>::infinity();
2156 prev = it.get_curr();
2176 constexpr size_t N = 50;
2179 for (
size_t i = 0; i <
N; ++i)
2183 for (
size_t i = 0; i <
N; ++i)
2189 constexpr size_t N = 100;
2192 for (
size_t i = 0; i <
N; ++i)
2193 a(i) =
static_cast<double>(
N - i);
2196 for (
size_t i = 1; i <
N; ++i)
2215 Record data[] = {{0, 0}, {2, 1}, {0, 2}, {1, 3}, {2, 4}, {1, 5}};
2216 const size_t n =
sizeof(data) /
sizeof(data[0]);
2217 const size_t num_buckets = 3;
2219 auto key = [](
const Record &
r) ->
size_t {
return r.group; };
2220 auto cmp = [](
const Record & a,
const Record & b) {
return a.group < b.group; };
2225 for (
size_t i = 1; i < n; ++i)
2243 int a[] = {3, 1, 2};
2245 const size_t num_buckets = 0;
2246 auto key = [](
const int &) ->
size_t {
return 0; };
2258 constexpr size_t N = 200;
2261 for (
size_t i = 0; i <
N; ++i)
2262 a(i) =
static_cast<int>(i);
2265 for (
size_t i = 1; i <
N; ++i)
2271 constexpr size_t N = 200;
2274 for (
size_t i = 0; i <
N; ++i)
2275 a(i) =
static_cast<int>(
N - i);
2278 for (
size_t i = 1; i <
N; ++i)
2284 int a[] = {5, 3, 8, 1, 9, 2, 7, 4, 6, 0};
2285 timsort(
static_cast<int*
>(a),
size_t{10});
2286 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
2291 constexpr size_t N = 10000;
2294 std::mt19937
gen(42);
2295 std::uniform_int_distribution<int> dist(-1000000, 1000000);
2296 for (
size_t i = 0; i <
N; ++i)
2300 for (
size_t i = 1; i <
N; ++i)
2306 if (
not std::getenv(
"ENABLE_PERF_TESTS"))
2307 GTEST_SKIP() <<
"Skipping perf test (set ENABLE_PERF_TESTS to enable)";
2309 constexpr size_t N = 100000;
2312 std::mt19937
gen(42);
2313 std::uniform_int_distribution<int> dist(-1000000, 1000000);
2314 for (
size_t i = 0; i <
N; ++i)
2317 auto start = std::chrono::steady_clock::now();
2319 auto end = std::chrono::steady_clock::now();
2321 auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
2324 if (
const char *
env_ms = std::getenv(
"TIMSORT_MAX_MS"))
2325 max_ms = std::atol(
env_ms);
2329 for (
size_t i = 1; i <
N; ++i)
2335 constexpr size_t N = 100;
2338 for (
size_t i = 0; i <
N; ++i)
2342 for (
size_t i = 0; i <
N; ++i)
2348 constexpr size_t N = 200;
2352 for (
size_t i = 0; i <
N / 2; ++i)
2353 a(i) =
static_cast<int>(i * 2);
2355 for (
size_t i =
N / 2; i <
N; ++i)
2356 a(i) =
static_cast<int>((i -
N / 2) * 2 + 1);
2359 for (
size_t i = 1; i <
N; ++i)
2365 constexpr size_t N = 50;
2368 std::mt19937
gen(99);
2369 for (
size_t i = 0; i <
N; ++i)
2370 a(i) =
static_cast<int>(
gen() % 1000);
2373 for (
size_t i = 1; i <
N; ++i)
2381 for (
size_t i = 1; i < a.
size(); ++i)
2388 for (
int x : {9, 1, 8, 2, 7, 3, 6, 4, 5, 0})
2392 for (
size_t i = 1; i < a.
size(); ++i)
2398 int a[] = {5, 3, 8, 1, 9, 2, 7, 4, 6, 0};
2400 EXPECT_TRUE(std::is_sorted(std::begin(a), std::end(a)));
2408 int prev = std::numeric_limits<int>::min();
2412 prev = it.get_curr();
2445 {3, 0}, {1, 1}, {4, 2}, {1, 3}, {5, 4},
2446 {9, 5}, {2, 6}, {6, 7}, {5, 8}, {3, 9}
2448 const size_t n =
sizeof(data) /
sizeof(data[0]);
2450 auto cmp = [](
const Record & a,
const Record & b) {
return a.key < b.key; };
2454 for (
size_t i = 1; i < n; ++i)
2455 ASSERT_LE(data[i - 1].key, data[i].key);
2458 for (
size_t i = 1; i < n; ++i)
2459 if (data[i - 1].key == data[i].key)
2461 <<
"Stability violated at index " << i;
2484 constexpr size_t N = 500;
2487 for (
size_t i = 0; i <
N; ++i)
2488 a(i) =
static_cast<int>(i);
2491 std::mt19937
gen(12);
2492 for (
int k = 0;
k < 10; ++
k)
2494 size_t i =
gen() %
N;
2495 size_t j =
gen() %
N;
2496 std::swap(a(i), a(j));
2500 for (
size_t i = 1; i <
N; ++i)
2506 int a[] = {9, 5, 3, 8, 1, 7, 2, 6, 4, 0};
2511 for (
int i = 3; i <= 7; ++i)
2534 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)
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.
Dynamic singly linked list with functional programming support.
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.
int cmp(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
constexpr size_t compute_minrun(size_t n) noexcept
Compute the minimum run length for timsort.
Main namespace for Aleph-w library functions.
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.
std::pair< bool, size_t > search_inversion(const Container< T > &cont, const Compare &cmp=Compare())
Find the first inversion in a container.
Dnode< T > * dlink_random_search(Dlink &list, const T &x, const Compare &cmp=Compare())
Random search for an element in a dlink list.
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.
void heapsort(T *array, const size_t n, const Compare &cmp=Compare())
Sort an array using the heapsort algorithm.
Itor2 copy(Itor1 sourceBeg, const Itor1 &sourceEnd, Itor2 destBeg)
Copy elements from one range to another.
void mergesort(T *a, const long l, const long r, std::vector< T > &buf, Compare cmp)
Sort an array using merge sort with a reusable buffer.
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
T * bsearch(C< T > &a, const T &x, const Compare &cmp=Compare())
Search for a value in a sorted container returning a pointer.
DynArray< size_t > build_index(const C< T > &a, const Compare &cmp=Compare())
Build an index array for indirect sorting.
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 shellsort(DynArray< T > &a, const Compare &cmp=Compare())
Sort a dynamic array using Shell sort.
DynArray< const T * > build_index_ptr(const C< T > &a, const Compare &cmp=Compare())
Build an index array of pointers for indirect sorting (const version).
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.