Skip to content

Commit e1a8b5e

Browse files
committed
Implement partial_sort_copy.
1 parent 69927a3 commit e1a8b5e

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

array_alg.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,15 @@ ALGDEF void NS(partial_sort)(
673673
void *compare_ctx
674674
);
675675

676+
ALGDEF T *NS(partial_sort_copy)(
677+
const T *first,
678+
const T *last,
679+
T *out_first,
680+
T *out_last,
681+
int (*compare)(const T*, const T*, void*),
682+
void *compare_ctx
683+
);
684+
676685
ALGDEF void NS(nth_element)(
677686
T *first,
678687
T *nth,
@@ -2109,6 +2118,42 @@ ALGDEF void NS(partial_sort)(
21092118
NS(sort_heap)(first, middle, compare, compare_ctx);
21102119
}
21112120

2121+
ALGDEF T *NS(partial_sort_copy)(
2122+
const T *first,
2123+
const T *last,
2124+
T *out_first,
2125+
T *out_last,
2126+
int (*compare)(const T*, const T*, void*),
2127+
void *compare_ctx
2128+
)
2129+
{
2130+
size_t n1 = last - first;
2131+
size_t n2 = out_last - out_first;
2132+
2133+
size_t n = (n2 < n1) ? n2 : n1;
2134+
out_last = out_first + n;
2135+
2136+
if (n == 0) { return out_last; }
2137+
2138+
NS(copy_n)(first, n, out_first);
2139+
first += n;
2140+
2141+
NS(make_heap_n)(out_first, n, compare, compare_ctx);
2142+
2143+
while (first != last)
2144+
{
2145+
if (compare(first, out_first, compare_ctx) < 0)
2146+
{
2147+
NS(pop_heap_n)(out_first, n, compare, compare_ctx);
2148+
*(out_last - 1) = *first;
2149+
NS(push_heap_n)(out_first, n, compare, compare_ctx);
2150+
}
2151+
++first;
2152+
}
2153+
NS(sort_heap)(out_first, out_last, compare, compare_ctx);
2154+
return out_last;
2155+
}
2156+
21122157
ALGDEF void NS(nth_element)(
21132158
T *first,
21142159
T *nth,

test/tests.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,25 @@ void test_partial_sort() {
589589
}
590590
}
591591

592+
void test_partial_sort_copy() {
593+
enum { N = 100 };
594+
int nums[N];
595+
for (int i = 0; i < N; ++i) {
596+
nums[i] = i;
597+
}
598+
599+
for (int iteration = 0; iteration < 1000; ++iteration) {
600+
intv_random_shuffle(nums, nums + N);
601+
602+
int top[10];
603+
intv_partial_sort_copy(nums, nums + N, top, top + 10, compare_int, NULL);
604+
605+
for (int i = 0; i < 10; ++i) {
606+
assert(top[i] == i);
607+
}
608+
}
609+
}
610+
592611
typedef void (*SortFunc)(int*, int*, int (*cmp)(const int*, const int*, void*), void*);
593612

594613
static inline
@@ -811,6 +830,7 @@ int main() {
811830
printf("-- test_sort_partition -- \n"); test_sort_partition();
812831
printf("-- test_nth_element --\n"); test_nth_element();
813832
printf("-- test_partial_sort --\n"); test_partial_sort();
833+
printf("-- test_partial_sort_copy --\n"); test_partial_sort_copy();
814834
printf("-- test_heap_sort --\n"); test_heap_sort();
815835
printf("-- test_insertion_sort --\n"); test_insertion_sort();
816836
printf("-- test_stable_sort --\n"); test_stable_sort();

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy