94#ifndef TPL_SORT_UTILS_H
95#define TPL_SORT_UTILS_H
159 template <
template <
typename>
class Container,
typename T,
167 const T & first = it.get_curr();
168 const T *prev = &first;
170 for (; it.has_curr(); it.next_ne())
172 const T & curr = it.get_curr();
173 if (
cmp(curr, *prev))
202 template <
template <
typename>
class Container,
typename T,
205 const Compare &
cmp = Compare())
208 return std::make_pair(
true, 0);
211 const T & first = it.get_curr();
212 const T *prev = &first;
215 for (; it.has_curr(); it.next_ne(), ++i)
217 const T & curr = it.get_curr();
218 if (
cmp(curr, *prev))
219 return std::make_pair(
false, i);
223 return std::make_pair(
true, i);
245 template <
template <
typename>
class Container,
typename T,
253 const T & first = it.get_curr();
254 const T *prev = &first;
256 for (; it.has_curr(); it.next_ne())
258 const T & curr = it.get_curr();
259 if (
cmp(*prev, curr))
288 template <
template <
typename>
class Container,
typename T,
297 const T & first = it.get_curr();
298 const T *prev = &first;
301 for (; it.has_curr(); it.next_ne(), ++i)
303 const T & curr = it.get_curr();
304 if (
cmp(curr, *prev))
345 template <
typename T,
class Compare = Aleph::less<T>>
353 for (
size_t i = 0,
min, j; i < n - 1; ++i)
355 for (
min = i, j = i + 1; j < n; ++j)
360 std::swap(a[
min], a[i]);
386 template <
class Link,
class Compare>
390 typename Link::Iterator it(
const_cast<Link &
>(list));
393 for (it.next(); it.has_curr(); it.next_ne())
395 Link *curr = it.get_curr();
403 template <
class Compare>
410 template <
class Compare>
434 template <
class Compare>
449 template <
typename Tlink,
450 template <
class>
class Tnode,
451 typename T,
class Compare>
463 noexcept(
noexcept(std::declval<const Compare&>()(std::declval<const T&>(), std::declval<const T&>())))
465 auto *n1 =
static_cast<Tnode<T> *
>(l1);
466 auto *n2 =
static_cast<Tnode<T> *
>(l2);
470 return cmp(n1->get_data(), n2->get_data());
475 noexcept(
noexcept(std::declval<const Compare&>()(std::declval<const T&>(), std::declval<const T&>())))
481 return cmp(n->get_data(), x);
485 template <
typename T,
class Compare>
495 template <
typename T,
class Compare>
518 template <
typename T,
class Compare = Aleph::less<T>>
546 template <
typename T,
class Equal = Aleph::equal_to<T>>
551 for (
long i =
l; i <= r; ++i)
552 if (
eq(a[i], x))
return i;
590 template <
typename T,
class Equal = Aleph::equal_to<T>>
593 const long l,
const long r, Equal
eq = Equal())
595 for (
long i =
l; i <= r; ++i)
603 template <
class Link,
typename T,
class Equal>
606 for (
typename Link::Iterator it(
const_cast<Link &
>(list));
607 it.has_curr(); it.next_ne())
608 if (
Link *curr = it.get_curr();
eq(curr, x))
614 template <
typename T,
class Equal = Aleph::equal_to<T>>
622 template <
typename T,
class Equal = Aleph::equal_to<T>>
649 template <
typename T,
class Equal = Aleph::equal_to<T>>
655 const auto & base =
static_cast<const Dlink &
>(list);
661 template <
typename T,
class Equal = Aleph::equal_to<T>>
664 Equal &&
eq = Equal())
688 template <
typename T,
class Equal = Aleph::equal_to<T>>
695 return ret !=
nullptr ? &
ret->get_data() :
nullptr;
698 template <
typename T,
class Equal = Aleph::equal_to<T>>
705 T & curr = it.get_curr_ne();
712 template <
typename T,
class Equal = Aleph::equal_to<T>>
719 T & curr = it.get_curr_ne();
741 template <
typename T,
class Compare = Aleph::less<T>>
746 for (
long i =
l + 1; i <= r; ++i)
757 template <
typename T,
class Compare = Aleph::less<T>>
768 template <
typename T,
class Compare = Aleph::greater<T>>
778 template <
typename T,
class Compare = Aleph::less<T>>
803 template <
typename T,
class Compare = Aleph::less<T>>
807 const auto & base =
static_cast<const Dnode<T> &
>(list);
810 return ret !=
nullptr ? &(
ret->get_data()) :
nullptr;
813 template <
typename T,
class Compare = Aleph::less<T>>
837 template <
typename T,
class Compare = Aleph::less<T>>
848 template <
typename T,
class Compare = Aleph::greater<T>>
890 template <
typename T,
class Compare = Aleph::less<T>>
893 const Compare &
cmp = Compare())
898 for (
long i =
l, j; i <= r; ++i)
901 for (j = i; j >
l and cmp(
tmp, a[j - 1]); --j)
921 template <
class Compare>
935 template <
class Compare>
971 <<
"insert_sorted(): reached end of list traversal without inserting";
985 template <
class ListType,
class Compare>
993 aux.
append(list.remove_first());
1000 template <
typename T,
class Compare = Aleph::less<T>>
1009 template <
typename T,
class Compare = Aleph::less<T>>
1016 return std::move(
l);
1030 template <
typename T,
class Compare = Aleph::less<T>>
1066 template <
typename T,
class Compare = Aleph::less<T>>
1068 void merge(
T *a,
const long l,
const long m,
const long r,
1069 std::vector<T> &
buf,
const Compare &
cmp = Compare())
1071 const long s = r -
l + 1;
1075 if (
buf.
size() <
static_cast<size_t>(s))
1076 buf.resize(
static_cast<size_t>(s));
1080 for (
long i =
l; i <= m; ++i)
1085 for (
long j = m + 1; j <= r; ++j)
1092 for (
long k =
l;
k <= r; ++
k)
1094 a[
k] = std::move(
buf[i++]);
1096 a[
k] = std::move(
buf[j--]);
1113 template <
typename T,
class Compare = Aleph::less<T>>
1115 void merge(
T *a,
const long l,
const long m,
const long r,
1116 const Compare &
cmp = Compare())
1119 buf.reserve(r -
l + 1);
1123 template <
typename T,
class Compare>
1129 const long m =
l + (r -
l) / 2;
1134 if (
not cmp(a[m + 1], a[m]))
1174 template <
typename T,
class Compare = Aleph::less<T>>
1182 buf.reserve(r -
l + 1);
1211 template <
typename Tlist,
class Compare>
1214 const Compare &
cmp = Compare())
1216 assert(result.is_empty());
1219 if (
cmp(l1.get_first_ne(), l2.get_first_ne()))
1220 result.append(l1.remove_first_ne());
1222 result.append(l2.remove_first_ne());
1225 result.concat_list(l2);
1227 result.concat_list(l1);
1248 template <
typename T,
class Compare = Aleph::less<T>>
1251 const Compare &
cmp = Compare())
1286 template <
typename Tlist,
class Compare>
1290 if (list.is_unitarian_or_empty())
1320 template <
template <
typename>
class Tlist,
typename T,
1326 if (list.is_unitarian_or_empty())
1329 if (list.size() <=
lsz)
1344 template <
template <
typename>
class Tlist,
typename T,
1349 if (list.is_unitarian_or_empty())
1381 template <
typename T,
class Compare = Aleph::less<T>>
1408 template <
typename T,
class Compare = Aleph::less<T>>
1415 template <
typename T,
class Compare = Aleph::less<T>>
1423 template <
typename T,
class Compare = Aleph::less<T>>
1428 return std::move(list);
1431 template <
typename T,
class Compare = Aleph::less<T>>
1443 std::swap(a[p], a[r]);
1452 while (
cmp(a[++i], a[r])) {}
1454 while (
cmp(a[r], a[--j]))
1462 std::swap(a[i], a[j]);
1465 std::swap(a[i], a[r]);
1504 template <
typename T,
class Compare = Aleph::less<T>>
1517 template <
typename T,
class Compare = Aleph::less<T>>
1524 const long left_size =
pivot -
l;
1525 const long right_size = r -
pivot;
1528 if (left_size < right_size)
1557 template <
typename T,
class Compare = Aleph::less<T>>
1560 const Compare &
cmp = Compare())
1578 template <
typename T,
class Compare>
1581 noexcept(
noexcept(
cmp(a[0], a[0])) && std::is_nothrow_swappable_v<T>)
1583 const long m =
l + (r -
l) / 2;
1585 if (
cmp(a[r], a[
l]))
1586 std::swap(a[
l], a[r]);
1587 if (
cmp(a[m], a[
l]))
1588 std::swap(a[m], a[
l]);
1589 if (
cmp(a[r], a[m]))
1590 std::swap(a[r], a[m]);
1632 template <
typename T,
class Compare = Aleph::less<T>>
1642 typedef std::pair<long, long>
Partition;
1646 while (stack.
size() > 0)
1649 const long diff = p.second - p.first;
1697 template <
typename T,
class Compare>
1699 const Compare &
cmp)
1774 template <
typename T,
class Compare = Aleph::less<T>>
1781 const auto n =
static_cast<size_t>(r -
l + 1);
1807 template <
typename T,
class Compare = Aleph::less<T>>
1843 template <
typename T,
class Compare = Aleph::less<T>>
1849 const auto n =
static_cast<size_t>(end - begin);
1877 template <
typename T,
class Compare = Aleph::less<T>>
1881 const size_t n = arr.
size();
1901 template <
class Compare>
1947 template <
typename T,
class Compare = Aleph::less<T>>
1953 template <
typename T,
class Compare>
1976 template <
typename T,
class Compare = Aleph::less<T>>
2020 template <
typename T,
class Compare = Aleph::less<T>>
2023 const Compare &
cmp = Compare())
2108 template <
typename T,
class Compare = Aleph::less<T>>
2111 const Compare &
cmp = Compare())
2126 template <
typename T,
class Compare = Aleph::less<T>>
2129 const Compare &
cmp = Compare())
2170 template <
typename T,
class Compare>
2173 const Compare &
cmp = Compare())
2202 list.
swap(&smaller);
2238 template <
typename T,
class Compare = Aleph::less<T>>
2273 template <
typename T,
class Compare = Aleph::less<T>>
2282 template <
typename T,
class Compare>
2285 const Compare &
cmp)
2299 template <
typename T,
class Compare,
typename Container>
2302 const Compare &
cmp)
2309 const long m =
l + (r -
l) / 2;
2312 const T &
la = a(
l);
2313 const T &
ra = a(r);
2314 const T &
ma = a(m);
2334 template <
typename T,
class Compare = Aleph::less<T>>
2337 const Compare &
cmp = Compare())
2347 template <
typename T,
class Compare = Aleph::less<T>>
2350 const Compare &
cmp = Compare())
2355 template <
typename T,
class Compare,
typename Container>
2358 const Compare &
cmp)
2373 while (
cmp(a(++i), a(r))) {}
2375 while (
cmp(a(r), a(--j)))
2382 std::swap(a(i), a(j));
2385 std::swap(a(i), a(r));
2390 template <
typename T,
class Compare = Aleph::less<T>>
2393 const Compare &
cmp = Compare())
2398 template <
typename T,
class Compare = Aleph::less<T>>
2401 const Compare &
cmp = Compare())
2406 template <
typename T,
class Compare>
2409 const long l,
const long r,
2410 const Compare &
cmp = Compare())
2426 template <
typename T,
class Compare>
2429 const long l,
const long r,
2430 const Compare &
cmp = Compare())
2446 template <
typename T,
class Compare = Aleph::less<T>>
2452 const long n =
static_cast<long>(
n_sz) - 1;
2458 template <
typename T,
class Compare = Aleph::less<T>>
2464 const long n =
static_cast<long>(
n_sz) - 1;
2510 template <
typename T,
class Compare = Aleph::less<T>>
2512 const Compare &
cmp = Compare())
2519 template <
typename T,
class Compare = Aleph::less<T>>
2521 Compare &&
cmp = Compare())
2548 template <
class Compare>
2550 const Compare &
cmp = Compare())
2623 template <
typename T,
class Compare = Aleph::less<T>>
2654 template <
typename T,
class Compare = Aleph::less<T>>
2659 auto *p =
static_cast<Dnode<T> *
>(link);
2661 return p !=
nullptr ? &(p->get_data()) :
nullptr;
2683 template <
typename T,
class Compare = Aleph::less<T>>
2687 const long n =
static_cast<long>(a.
size());
2691 for (
long i = 0; i < n - 1; ++i)
2695 for (
long j = i + 1; j < n; ++j)
2700 std::swap(a(
min), a(i));
2734 template <
typename T,
class Compare = Aleph::less<T>>
2738 const long n =
static_cast<long>(a.
size());
2742 for (
long i = 0; i < n - 1; ++i)
2743 for (
long j = n - 1; j > i; --j)
2744 if (
cmp(a(j), a(j - 1)))
2745 std::swap(a(j - 1), a(j));
2774 template <
template <
typename>
class C,
typename T,
2779 for (
long i =
l + 1; i <= r; i++)
2794 template <
template <
typename>
class C,
typename T,
2799 const auto n = a.size();
2839 template <
typename T,
class Compare = Aleph::less<T>>
2843 const long n = a.
size();
2851 1, 4, 10, 23, 57, 132, 301, 701, 1750, 4024, 9233,
2852 21223, 48805, 112217, 258100, 593630, 1365513, 3140680
2865 for (
long i =
h; i < n; i++)
2867 T tmp = std::move(a(i));
2872 a(j) = std::move(a(j -
h));
2876 a(j) = std::move(
tmp);
2882 inline static long back_index(
const long i)
noexcept {
return i - 1; }
2885 template <
typename T,
class Compare>
2890 for (
long i = n; i > 1; i = p)
2901 template <
typename T,
class Compare>
2928 template <
typename T,
class Compare>
2947 template <
typename T,
class Compare>
2962 noexcept(
noexcept(std::declval<const Compare &>()(
e2,
e1)))
3008 template <
typename T,
class Compare = Aleph::less<T>>
3012 const long n = a.
size();
3020 for (
long i = n / 2; i >= 1; --i)
3024 for (
long i = n; i >= 2; --i)
3026 std::swap(a(0), a(i - 1));
3031 template <
template <
typename>
class C,
typename T,
3054 std::swap(a(i), a(j));
3057 std::swap(a(i), a(r));
3062 template <
typename T,
class Compare = Aleph::less<T>>
3065 const Compare &
cmp = Compare())
3082 template <
class Stack,
class A,
class B>
3118 template <
typename T,
class Compare = Aleph::less<T>>
3122 long l = 0, r = a.
size() - 1;
3139 push2(stack, i + 1, r);
3143 push2(stack, i + 1, r);
3158 template <
typename T,
class Compare>
3165 long c = start << 1;
3186 template <
typename T,
class Compare>
3189 const Compare &
cmp)
3191 const long n = r -
l + 1;
3198 for (
long i = n / 2; i >= 1; --i)
3202 for (
long i = n; i >= 2; --i)
3204 std::swap(a(
l), a(
l + i - 1));
3213 template <
typename T,
class Compare>
3215 const Compare &
cmp)
3275 template <
typename T,
class Compare = Aleph::less<T>>
3279 const long n = a.
size();
3310 template <
typename T,
class Compare = Aleph::less<T>>
3313 const Compare &
cmp = Compare())
3317 for (
long i =
l + 1; i <= r; i++)
3328 template <
typename T,
class Compare = Aleph::greater<T>>
3331 const Compare &
cmp = Compare())
3381 template <
template <
typename>
class C,
typename T,
3385 const Compare &
cmp = Compare())
3391 if (
long m =
l + (r -
l) / 2;
cmp(x, a(m)))
3393 else if (
cmp(a(m), x))
3401 template <
template <
typename>
class C,
typename T,
3405 const Compare &
cmp = Compare())
3411 if (
long m =
l + (r -
l) / 2;
cmp(x, *a(m)))
3413 else if (
cmp(*a(m), x))
3421 template <
template <
typename>
class C,
typename T,
3426 const auto n = a.size();
3459 template <
template <
typename>
class C,
typename T,
3464 const auto n = a.size();
3471 template <
template <
typename>
class C,
typename T,
3475 const Compare &
cmp = Compare())
3478 const auto n = a.
size();
3490 for (
long i = idx - 1; i >= 0; --i)
3507 template <
template <
typename>
class C,
typename T,
3519 template <
template <
typename>
class C,
typename T,
3531 template <
template <
typename>
class C,
typename T,
3545 for (
long i = idx - 1; i >= 0; --i)
3547 T *ptr =
const_cast<T *
>(&a(i));
3555 for (
long i = idx + 1, n = a.size(); i < n; ++i)
3557 T *ptr =
const_cast<T *
>(&a(i));
3566 template <
template <
typename>
class C,
typename T,
3572 const auto n = a.
size();
3584 for (
long i = idx - 1; i >= 0; --i)
3594 for (
long i = idx + 1, n = a.size(); i < n; ++i)
3638 template <
template <
typename>
class C,
typename T,
3675 template <
template <
typename>
class C,
typename T,
3685 T *ptr =
const_cast<T *
>(&a(idx));
3689 const long mid = idx;
3691 for (
long i = idx - 1; i >= 0; --i)
3693 ptr =
const_cast<T *
>(&a(i));
3701 for (
long i = idx + 1, n = a.size(); i < n; ++i)
3703 ptr =
const_cast<T *
>(&a(i));
3712 template <
template <
typename>
class C,
typename T,
3726 for (
long i = idx - 1; i >= 0; --i)
3736 for (
long i = idx + 1, n = a.size(); i < n; ++i)
3782 template <
template <
typename>
class C,
typename T,
3787 const size_t & n = a.
size();
3789 ret.reserve(a.size());
3790 for (
size_t i = 0; i < n; ++i)
3794 [&a, &
cmp](
size_t i,
size_t j) {
return cmp(a(i), a(j)); });
3824 template <
template <
typename>
class C,
typename T,
3829 const size_t & n = a.
size();
3831 ret.reserve(a.size());
3832 for (
size_t i = 0; i < n; ++i)
3870 template <
template <
typename>
class C,
typename T,
3876 const size_t n = a.size();
3880 size_t l = 0, r = n - 1;
3903 static_cast<long>(
l),
3904 static_cast<long>(r),
3907 const size_t left_size = i >
l ? i -
l : 0;
3908 const size_t right_size = r > i ? r - i : 0;
3910 if (left_size > right_size)
3915 push2(stack, i + 1, r);
3920 push2(stack, i + 1, r);
3957 template <
typename T,
class Compare = Aleph::less<T>>
3960 const Compare &
cmp = Compare())
3965 const long m =
l + (r -
l) / 2;
4005 template <
typename T,
class Compare = Aleph::less<T>>
4008 const Compare &
cmp = Compare())
4012 long m =
l + (r -
l) / 2;
4015 else if (
cmp(a[m], x))
Exception handling system with formatted messages for Aleph-w.
#define ah_out_of_range_error_if(C)
Throws std::out_of_range if condition holds.
#define ah_logic_error()
Throws std::logic_error unconditionally.
#define ah_out_of_range_error()
Throws std::out_of_range unconditionally.
Functional programming utilities for Aleph-w containers.
General utility functions and helpers.
Simple dynamic array with automatic resizing and functional operations.
constexpr size_t size() const noexcept
Return the number of elements stored in the stack.
bool operator()(Tlink *l1, Tlink *l2) const noexcept(noexcept(std::declval< const Compare & >()(std::declval< const T & >(), std::declval< const T & >())))
Compare_Tnode(Compare cmp_fct=Compare()) noexcept(std::is_nothrow_copy_constructible_v< Compare >)
void next_ne() noexcept
Move the iterator one position backward guaranteeing no exception.
bool has_curr() const noexcept
Return true if the iterator has current item.
Dlink * get_curr() const
Return the current node of iterator.
Doubly linked circular list node.
Dlink * remove_next() noexcept
Remove the item that is after this
void concat_list(Dlink *head) noexcept
Concatenate list head to list this
constexpr bool is_unitarian_or_empty() const noexcept
Return true if this (as header node) has zero or one element.
constexpr bool is_empty() const noexcept
Return true if this (as header node) is empty.
void append(Dlink *node) noexcept
Insert node before this.
void swap(Dlink *link) noexcept
Swap this with list whose header is link.
Node belonging to a double circular linked list with header node.
T & get_data() noexcept
Return a modifiable reference to the data contained in the node.
size_t size() const noexcept
Return the current dimension of array.
bool exist(const size_t i) const
Return true if the i-th entry is accessible.
Dynamic doubly linked list with O(1) size and bidirectional access.
Iterator on the items of list.
T & get_curr_ne() const noexcept
Return the current link guaranteeing no exception. Be careful.
Dynamic singly linked list with functional programming support.
T & insert(const T &item)
Insert a new item by copy.
T & append(const T &item)
Append a new item by copy.
T & push(const T &data) noexcept
Push a copy of data
size_t size() const noexcept
Return the number of elements stored in the stack.
bool is_empty() const noexcept
Return true if stack is empty.
T pop() noexcept
Pop by moving the top of stack.
void next_ne() noexcept
Move the iterator one position forward guaranteeing no exception.
void next()
Move the iterator one item forward.
Slinknc * get_curr() const
Return the current node on which the iterator is positioned.
bool has_curr() const noexcept
Return true if iterator has current item.
Single linked list of nodes.
Slinknc * get_first() const noexcept
Return list first element.
constexpr bool is_empty() const noexcept
Return true if list is empty.
void concat_list(HTList &l) noexcept
void append(Slinknc *link) noexcept
Insert link as last element.
size_t split_list(HTList &l, HTList &r) noexcept
It divides 'this' into two equal lists without modifying elements order.
Slinknc * remove_first_ne() noexcept
size_t size() const noexcept
Count the number of elements of the list.
void insert(Slinknc *link) noexcept
Insert link as first element.
Slinknc * get_last() const noexcept
Return the last item of the list (nullptr if the list is empty)
size_t split_list_ne(HTList &l, HTList &r) noexcept
bool is_unitarian_or_empty() const noexcept
Return true if list contains one element or is empty.
Comparator wrapper that inverts the comparison order.
Negate_Compare(Compare __cmp=Compare()) noexcept(std::is_nothrow_copy_assignable_v< Compare >)
Construct from a comparator.
bool operator()(const T &e1, const T &e2) const noexcept(noexcept(std::declval< const Compare & >()(e2, e1)))
Compare in reverse order: returns cmp(e2, e1).
Link of a single linked list non-circular and without header node.
void insert(Slinknc *p) noexcept
Insert p after this
Node belonging to a single non-circular linked list without header node.
__gmp_expr< typename __gmp_resolve_expr< T, V >::value_type, __gmp_binary_expr< __gmp_expr< T, U >, __gmp_expr< V, W >, __gmp_min_function > > min(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
int cmp(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
Singly linked list implementations with head-tail access.
const long double offset[]
Offset values indexed by symbol string length (bounded by MAX_OFFSET_INDEX)
Main namespace for Aleph-w library functions.
DynList< size_t > binary_search_dup(const C< T > &a, const T &x, const Compare &cmp=Compare())
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.
long select_pivot(T *a, long l, long r, const Compare &cmp=Compare()) noexcept(noexcept(cmp(a[0], a[0])) &&std::is_nothrow_swappable_v< T >)
long select_pivot_op_impl(const Container &a, const long l, const long r, const Compare &cmp)
std::pair< bool, size_t > search_inversion(const Container< T > &cont, const Compare &cmp=Compare())
Find the first inversion in a container.
void heapsort_subrange(DynArray< T > &a, const long l, const long r, const Compare &cmp)
Heapsort a subrange of a DynArray.
size_t introsort_depth_limit(size_t n) noexcept
Compute the depth limit for introsort.
bool eq(const C1 &c1, const C2 &c2, Eq e=Eq())
Check equality of two containers using a predicate.
long select_pivot_op(const DynArray< T > &a, const long l, const long r, const Compare &cmp=Compare())
Selects a pivot element as the median between the ends and the center.
Dnode< T > * dlink_random_search(Dlink &list, const T &x, const Compare &cmp=Compare())
Random search for an element in a dlink list.
void sift_down(T *ptr, const size_t l, const size_t r, Compare &cmp)
Restore the heap property by moving the element at position l downwards.
DynArray< T * > build_index_ptr(const C< T > &a, const Compare &cmp=Compare())
Builds and returns an array of pointers to the elements of container a sorted according to the compar...
void sift_down_subrange(DynArray< T > &a, long start, const long n, const long offset, const Compare &cmp)
Sift down operation for heapsort on a DynArray subrange.
void quicksort_no_tail(T *a, long l, long r, const Compare &cmp=Compare())
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.
size_t Quicksort_Threshold
Threshold for using quicksort vs simpler algorithms.
const int Not_Found
Return value for search functions when element is not found.
std::pair< TgtContainer< typename SrcContainer::Item_Type >, TgtContainer< typename SrcContainer::Item_Type > > partition(const SrcContainer &c, std::function< bool(const typename SrcContainer::Item_Type &)> operation)
Partition a container into two based on a predicate.
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.
void introsort_loop(T *a, long l, long r, size_t depth_limit, const Compare &cmp)
Internal recursive function for introsort.
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 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 about Dlink.
void heapsort(T *array, const size_t n, const Compare &cmp=Compare())
Sort an array using the heapsort algorithm.
void faster_heapsort(T *array, const size_t n, const Compare &cmp=Compare())
Optimized version of heapsort.
void mergesort(T *a, const long l, const long r, std::vector< T > &buf, Compare cmp)
T * bsearch(const C< T > &a, const T &x, const Compare &cmp=Compare())
std::decay_t< typename HeadC::Item_Type > T
DynArray< size_t > build_index(const C< T > &a, const Compare &cmp=Compare())
Build an index array for indirect sorting.
void list_insertion_sort(ListType &list, const Compare &cmp)
Sorts a list of simple nodes by insertion method.
static const T & __random_select(T *a, const long i, const long l, const long r, const Compare &cmp)
const T & random_select(DynArray< T > &a, const long i, const Compare &cmp=Compare())
static long back_index(const long i) noexcept
void bubble_sort(DynArray< T > &a, const Compare &cmp=Compare())
Sort a dynamic array using bubble sort.
bool diff(const C1 &c1, const C2 &c2, Eq e=Eq())
Check if two containers differ.
DynList< T * > bsearch_dup(const C< T > &a, const T &x, const Compare &cmp=Compare())
void quicksort(T *a, const long l, const long r, const Compare &cmp=Compare())
Sort an array using iterative quicksort with optimizations.
void insertion_sort(T *a, const long l, const long r, const Compare &cmp=Compare()) noexcept(noexcept(cmp(a[0], a[0])) &&std::is_nothrow_move_assignable_v< T >)
Sort an array using insertion sort.
void shellsort(DynArray< T > &a, const Compare &cmp=Compare())
Sort a dynamic array using Shell sort.
bool are_equals(const T &op1, const T &op2, Compare &&cmp=Compare())
Determines if operands are equal using a comparison operator.
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.
void quicksort_rec(T *a, const long l, const long r, const Compare &cmp=Compare())
Sorts an array using the quicksort method.
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.
long partition_op_impl(Container &a, const long l, const long r, const Compare &cmp)
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.
size_t Insertion_Threshold
Threshold for switching to insertion sort in hybrid algorithms.
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.
long partition_op(DynArray< T > &a, const long l, const long r, const Compare &cmp=Compare())
T & sift_up(T *ptr, const size_t l, const size_t r, Compare &cmp)
Restore the heap property by moving the element at position r upwards.
void merge_lists(Tlist &l1, Tlist &l2, Tlist &result, const Compare &cmp=Compare())
Merge two sorted lists into a single sorted list.
DynList< T > maps(const C &c, Op op)
Classic map operation.
void push2(Stack &stack, const A &a, const B &b)
void quicksort_op(C< T > &a, const Compare &cmp=Compare(), const size_t threshold=Quicksort_Threshold)
Optimized quicksort for containers using operator().
Compare_Dnode(const Compare &cmp=Compare()) noexcept(std::is_nothrow_copy_constructible_v< Compare >)
Fixed-capacity binary heap and heapsort algorithms.
Stack implementations backed by dynamic or fixed arrays.
Dynamic array container with automatic resizing.
Lazy and scalable dynamic array implementation.
Dynamic doubly linked list implementation.