Skip to content

Commit d88104c

Browse files
committed
Improve partial_sort_copy
1 parent e1a8b5e commit d88104c

File tree

2 files changed

+51
-25
lines changed

2 files changed

+51
-25
lines changed

array_alg.h

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2127,31 +2127,36 @@ ALGDEF T *NS(partial_sort_copy)(
21272127
void *compare_ctx
21282128
)
21292129
{
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;
2130+
if (first == last || out_first == out_last) return out_first;
2131+
T *out = out_first;
2132+
*out = *first;
2133+
++out;
2134+
++first;
21402135

2141-
NS(make_heap_n)(out_first, n, compare, compare_ctx);
2136+
while (out != out_last)
2137+
{
2138+
if (first == last) {
2139+
NS(sort_heap)(out_first, out, compare, compare_ctx);
2140+
return out;
2141+
}
2142+
*out = *first;
2143+
++first;
2144+
++out;
2145+
NS(push_heap)(out_first, out, compare, compare_ctx);
2146+
}
21422147

21432148
while (first != last)
21442149
{
21452150
if (compare(first, out_first, compare_ctx) < 0)
21462151
{
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);
2152+
NS(pop_heap)(out_first, out, compare, compare_ctx);
2153+
*(out - 1) = *first;
2154+
NS(push_heap)(out_first, out, compare, compare_ctx);
21502155
}
21512156
++first;
21522157
}
2153-
NS(sort_heap)(out_first, out_last, compare, compare_ctx);
2154-
return out_last;
2158+
NS(sort_heap)(out_first, out, compare, compare_ctx);
2159+
return out;
21552160
}
21562161

21572162
ALGDEF void NS(nth_element)(

test/tests.c

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -590,19 +590,40 @@ void test_partial_sort() {
590590
}
591591

592592
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;
593+
{
594+
enum { N = 100 };
595+
int nums[N];
596+
for (int i = 0; i < N; ++i) {
597+
nums[i] = i;
598+
}
599+
600+
enum { M = 10 };
601+
for (int iteration = 0; iteration < 1000; ++iteration) {
602+
intv_random_shuffle(nums, nums + N);
603+
604+
int top[M];
605+
intv_partial_sort_copy(nums, nums + N, top, top + M, compare_int, NULL);
606+
607+
for (int i = 0; i < M; ++i) {
608+
assert(top[i] == i);
609+
}
610+
}
597611
}
612+
{
613+
enum { N = 10 };
614+
int nums[N];
615+
for (int i = 0; i < N; ++i) {
616+
nums[i] = i;
617+
}
618+
intv_reverse(nums, nums + N);
598619

599-
for (int iteration = 0; iteration < 1000; ++iteration) {
600-
intv_random_shuffle(nums, nums + N);
620+
enum { M = 100 };
601621

602-
int top[10];
603-
intv_partial_sort_copy(nums, nums + N, top, top + 10, compare_int, NULL);
622+
int top[M];
623+
int *out = intv_partial_sort_copy(nums, nums + N, top, top + M, compare_int, NULL);
624+
assert(out == top + N);
604625

605-
for (int i = 0; i < 10; ++i) {
626+
for (int i = 0; i < N; ++i) {
606627
assert(top[i] == i);
607628
}
608629
}

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