Skewheap (skewheap v0.5.0)

Skewheap - a mergable priority queue

Skewheaps are fun, weird, priority queues that self-balance over time. Their structural depth is not guaranteed and individual operations may vary in performance. That said, its amortized performance is roughly O(log n) (source).

Skewheaps' most interesting characteristic is that they can be very quickly merged together non-destructively, creating a new, balanced heap containing all elements of the source heaps.

examples

Examples

iex> {_skew, items} = 1..10 |> Enum.shuffle() |> Enum.into(Skewheap.new()) |> Skewheap.drain()
...> items
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

iex> a = 1..3 |> Enum.shuffle() |> Enum.into(Skewheap.new())
...> b = 4..6 |> Enum.shuffle() |> Enum.into(Skewheap.new())
...> {_skew, items} = Skewheap.merge(a, b) |> Skewheap.drain()
...> items
[1, 2, 3, 4, 5, 6]

Link to this section Summary

Functions

Removes all elements from the heap and returns them as a list.

Removes up to count elements from the heap and returns them as a list.

True when the Skewheap has no items in it.

Fills the heap with a list of items.

Returns true if element is present in the skewheap. Note that this requires a depth first search of the binary heap structure.

Merges two skew heaps into a new heap.

Returns a new Skewheap.

Returns the top element of the heap without removing it or :nothing if empty.

Adds a new element to the heap.

Returns the number of items in the Skewheap.

Retrieves the top element from the heap or :nothing if empty.

Link to this section Types

@type t() :: %Skewheap{root: skewnode(), size: non_neg_integer(), sorter: sorter()}

Link to this section Functions

@spec drain(t()) :: {t(), [any()]}

Removes all elements from the heap and returns them as a list.

examples

Examples

iex> {_skew, items} = 1..10 |> Enum.shuffle() |> Enum.into(Skewheap.new()) |> Skewheap.drain()
...> items
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Link to this function

drain(skew, count)

@spec drain(t(), non_neg_integer()) :: {t(), [any()]}

Removes up to count elements from the heap and returns them as a list.

examples

Examples

iex> {_skew, items} = 1..5 |> Enum.shuffle() |> Enum.into(Skewheap.new()) |> Skewheap.drain()
...> items
[1, 2, 3, 4, 5]

iex> {_skew, items} = 1..5 |> Enum.shuffle() |> Enum.into(Skewheap.new()) |> Skewheap.drain(3)
...> items
[1, 2, 3]

iex> {_skew, items} = 1..5 |> Enum.shuffle() |> Enum.into(Skewheap.new()) |> Skewheap.drain(5)
...> items
[1, 2, 3, 4, 5]
Link to this function

drain(skew, count, acc)

@spec drain(t(), non_neg_integer(), [any()]) :: {t(), [any()]}
Link to this macro

empty?(skew)

(macro)

True when the Skewheap has no items in it.

examples

Examples

iex> Skewheap.new() |> Skewheap.empty?()
true

iex> 1..10 |> Enum.shuffle() |> Enum.into(Skewheap.new()) |> Skewheap.empty?()
false
Link to this function

fill(skew, arg2)

@spec fill(t(), [any()]) :: t()

Fills the heap with a list of items.

examples

Examples

iex> {_skew, items} = Skewheap.fill(Skewheap.new(), 1..5 |> Enum.shuffle()) |> Skewheap.drain() ...> items [1, 2, 3, 4, 5]

Link to this function

member?(skew, element)

@spec member?(t(), any()) :: boolean()

Returns true if element is present in the skewheap. Note that this requires a depth first search of the binary heap structure.

examples

Examples

iex> s = 1..10 |> Enum.shuffle() |> Enum.into(Skewheap.new())
...> Skewheap.member?(s, 5)
true

iex> s = 1..10 |> Enum.shuffle() |> Enum.into(Skewheap.new())
...> Skewheap.member?(s, 15)
false

iex> Skewheap.member?(Skewheap.new(), 42)
false
@spec merge(t(), t()) :: t()

Merges two skew heaps into a new heap.

examples

Examples

iex> a = 1..3 |> Enum.shuffle() |> Enum.into(Skewheap.new())
...> b = 4..6 |> Enum.shuffle() |> Enum.into(Skewheap.new())
...> {_skew, items} = Skewheap.merge(a, b) |> Skewheap.drain()
...> items
[1, 2, 3, 4, 5, 6]
Link to this function

new(sorter \\ &<=/2)

@spec new(sorter()) :: t()

Returns a new Skewheap.

examples

Examples

iex> Skewheap.new() |> Skewheap.size()
0

iex> Skewheap.new() |> Skewheap.empty?()
true
@spec peek(t()) :: any()

Returns the top element of the heap without removing it or :nothing if empty.

examples

Examples

iex> 1..10 |> Enum.shuffle() |> Enum.into(Skewheap.new()) |> Skewheap.peek()
1

iex> Skewheap.new() |> Skewheap.peek()
:nothing
Link to this function

put(skew, payload)

@spec put(t(), any()) :: t()

Adds a new element to the heap.

examples

Examples

iex> s = Skewheap.new()
...> s = Skewheap.put(s, 42)
...> Skewheap.put(s, "fnord")
...> Skewheap.peek(s)
42
@spec size(t()) :: non_neg_integer()

Returns the number of items in the Skewheap.

examples

Examples

iex> Skewheap.new() |> Skewheap.size()
0

iex> 1..10 |> Enum.shuffle() |> Enum.into(Skewheap.new()) |> Skewheap.size()
10
@spec take(t()) :: {t(), any()}

Retrieves the top element from the heap or :nothing if empty.

examples

Examples

iex> {_skew, value} = Skewheap.new() |> Skewheap.take()
...> value
:nothing

iex> {skew, value} = [1,2,3] |> Enum.shuffle() |> Enum.into(Skewheap.new()) |> Skewheap.take()
...> {value, Skewheap.size(skew)}
{1, 2}