diff --git a/docs/src/heaps.md b/docs/src/heaps.md index 4a78ac587..52ee9beb9 100644 --- a/docs/src/heaps.md +++ b/docs/src/heaps.md @@ -23,6 +23,8 @@ extract_all!(h) # removes all elements and returns sorted array extract_all_rev!(h) # removes all elements and returns reverse sorted array +values(h) # returns the elements of the heap in an arbitrary order + sizehint!(h, n) # reserve capacity for at least `n` elements ``` @@ -40,6 +42,8 @@ update!(h, i, v) # updates the value of an element (referred to by the delete!(h, i) # deletes the node with handle i from the heap v, i = top_with_handle(h) # returns the top value of a heap and its handle + +ks = keys(h) # returns the handles associated with the heap in an arbitrary order ``` Currently, both min/max versions of binary heap (type `BinaryHeap`) and diff --git a/src/heaps/binary_heap.jl b/src/heaps/binary_heap.jl index f3850d5d6..25db7c171 100644 --- a/src/heaps/binary_heap.jl +++ b/src/heaps/binary_heap.jl @@ -106,6 +106,13 @@ Removes and returns the element at the top of the heap `h`. """ Base.pop!(h::BinaryHeap) = heappop!(h.valtree, h.ordering) +""" + values(h::BinaryHeap) + +Returns the elements of the heap in an arbitrary order. +""" +Base.values(h::BinaryHeap) = h.valtree + # Suggest that heap `h` reserve capacity for at least `n` elements. This can improve performance. function Base.sizehint!(h::BinaryHeap, n::Integer) sizehint!(h.valtree, n) diff --git a/src/heaps/minmax_heap.jl b/src/heaps/minmax_heap.jl index 25b877b08..98254d6d5 100644 --- a/src/heaps/minmax_heap.jl +++ b/src/heaps/minmax_heap.jl @@ -232,13 +232,20 @@ Remove up to the `k` largest values from the heap. return [popmax!(h) for _ in 1:min(length(h), k)] end - function Base.push!(h::BinaryMinMaxHeap, v) valtree = h.valtree push!(valtree, v) @inbounds _minmax_heap_bubble_up!(valtree, length(valtree)) end +""" + values(h::BinaryMinMaxHeap) + +Returns the elements of the heap in an arbitrary order. +""" +Base.values(h::BinaryMinMaxHeap) = h.valtree + + """ first(h::BinaryMinMaxHeap) diff --git a/src/heaps/mutable_binary_heap.jl b/src/heaps/mutable_binary_heap.jl index 699aa538c..fd98afaa4 100644 --- a/src/heaps/mutable_binary_heap.jl +++ b/src/heaps/mutable_binary_heap.jl @@ -246,6 +246,20 @@ end Base.pop!(h::MutableBinaryHeap{T}) where {T} = _binary_heap_pop!(h.ordering, h.nodes, h.node_map) +""" + keys(h::MutableBinaryHeap) + +Returns the handles of the heap in an arbitrary order. +""" +Base.keys(h::MutableBinaryHeap) = h.node_map + +""" + values(h::MutableBinaryHeap) + +Returns an iterator over the elements of the heap in an arbitrary order. +""" +Base.values(h::MutableBinaryHeap) = (h.nodes[i].value for i in h.node_map) + """ update!{T}(h::MutableBinaryHeap{T}, i::Int, v::T) diff --git a/test/test_binheap.jl b/test/test_binheap.jl index 2c7c2151a..4b7199f79 100644 --- a/test/test_binheap.jl +++ b/test/test_binheap.jl @@ -89,6 +89,10 @@ @test reverse(sort(vs)) == extract_all_rev!(BinaryMinHeap(vs)) end + @testset "values" begin + @test sort(vs) == sort(values(BinaryMinHeap(vs))) + end + @testset "push!" begin @testset "push! hmin" begin hmin = BinaryMinHeap{Int}() diff --git a/test/test_minmax_heap.jl b/test/test_minmax_heap.jl index 1c2a67b43..5a28c84df 100644 --- a/test/test_minmax_heap.jl +++ b/test/test_minmax_heap.jl @@ -114,6 +114,12 @@ using Base.Order: Forward, Reverse end end + @testset "values" begin + vs = [10, 4, 6, 1, 16, 2, 20, 17, 13, 5] + + @test sort(vs) == sort(values(BinaryMinMaxHeap{Int}(vs))) + end + @testset "empty!" begin h = BinaryMinMaxHeap([1, 4, 3, 10, 2]) ret = empty!(h) diff --git a/test/test_mutable_binheap.jl b/test/test_mutable_binheap.jl index e12c12313..80854a5f6 100644 --- a/test/test_mutable_binheap.jl +++ b/test/test_mutable_binheap.jl @@ -113,6 +113,8 @@ end @test isequal(list_values(h), vs) @test isequal(heap_values(h), [16, 14, 10, 8, 7, 3, 9, 1, 4, 2]) @test sizehint!(h, 100) === h + @test sort(vs) == sort(collect(values(h))) + @test 1:length(h) == sort(keys(h)) end @testset "make mutable binary custom ordering heap" begin