summaryrefslogtreecommitdiffstats
path: root/libcxx/test/algorithms/alg.sorting
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-07-22 06:07:09 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-07-22 06:07:09 +0000
commit8b5126027406918e5b1f6ff4be2e98d231bb7704 (patch)
treea691cbc8ee1a1b224bf20222ca8680deeac4ee44 /libcxx/test/algorithms/alg.sorting
parentfc3d8f0a78fe326cd5403e86cfc03b0abf668f31 (diff)
downloadbcm5719-llvm-8b5126027406918e5b1f6ff4be2e98d231bb7704.tar.gz
bcm5719-llvm-8b5126027406918e5b1f6ff4be2e98d231bb7704.zip
Fix std::make_heap's worst case time complexity
std::make_heap is currently implemented by iteratively applying a siftup-type algorithm. Since sift-up is O(ln n), this gives std::make_heap a worst case time complexity of O(n ln n). The C++ standard mandates that std::make_heap make no more than O(3n) comparisons, this makes our std::make_heap out of spec. Fix this by introducing an implementation of __sift_down and switch std::make_heap to create the heap using it. This gives std::make_heap linear time complexity in the worst case. This fixes PR20161. llvm-svn: 213615
Diffstat (limited to 'libcxx/test/algorithms/alg.sorting')
-rw-r--r--libcxx/test/algorithms/alg.sorting/alg.heap.operations/make.heap/make_heap_comp.pass.cpp23
1 files changed, 22 insertions, 1 deletions
diff --git a/libcxx/test/algorithms/alg.sorting/alg.heap.operations/make.heap/make_heap_comp.pass.cpp b/libcxx/test/algorithms/alg.sorting/alg.heap.operations/make.heap/make_heap_comp.pass.cpp
index 7bbdd09546c..4cde1a7d32e 100644
--- a/libcxx/test/algorithms/alg.sorting/alg.heap.operations/make.heap/make_heap_comp.pass.cpp
+++ b/libcxx/test/algorithms/alg.sorting/alg.heap.operations/make.heap/make_heap_comp.pass.cpp
@@ -35,14 +35,35 @@ struct indirect_less
void test(unsigned N)
{
int* ia = new int [N];
+ {
for (int i = 0; i < N; ++i)
ia[i] = i;
- {
std::random_shuffle(ia, ia+N);
std::make_heap(ia, ia+N, std::greater<int>());
assert(std::is_heap(ia, ia+N, std::greater<int>()));
}
+// Ascending
+ {
+ binary_counting_predicate<std::greater<int>, int, int> pred ((std::greater<int>()));
+ for (int i = 0; i < N; ++i)
+ ia[i] = i;
+ std::make_heap(ia, ia+N, std::ref(pred));
+ assert(pred.count() <= 3*N);
+ assert(std::is_heap(ia, ia+N, pred));
+ }
+
+// Descending
+ {
+ binary_counting_predicate<std::greater<int>, int, int> pred ((std::greater<int>()));
+ for (int i = 0; i < N; ++i)
+ ia[N-1-i] = i;
+ std::make_heap(ia, ia+N, std::ref(pred));
+ assert(pred.count() <= 3*N);
+ assert(std::is_heap(ia, ia+N, pred));
+ }
+
+// Random
{
binary_counting_predicate<std::greater<int>, int, int> pred ((std::greater<int>()));
std::random_shuffle(ia, ia+N);
OpenPOWER on IntegriCloud