improve document for heapqueue (#16107)

This commit is contained in:
flywind
2020-11-24 21:29:34 +08:00
committed by GitHub
parent 9a86198ed5
commit afb8b69c0a

View File

@@ -6,50 +6,48 @@
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
##[
The `heapqueue` module implements a
`heap data structure<https://en.wikipedia.org/wiki/Heap_(data_structure)>`_
that can be used as a
`priority queue<https://en.wikipedia.org/wiki/Priority_queue>`_.
Heaps are arrays for which `a[k] <= a[2*k+1]` and `a[k] <= a[2*k+2]` for
all `k`, counting elements from 0. The interesting property of a heap is that
`a[0]` is always its smallest element.
Basic usage
-----------
.. code-block:: Nim
import heapqueue
## The `heapqueue` module implements a
## `heap data structure<https://en.wikipedia.org/wiki/Heap_(data_structure)>`_
## that can be used as a
## `priority queue<https://en.wikipedia.org/wiki/Priority_queue>`_.
## Heaps are arrays for which `a[k] <= a[2*k+1]` and `a[k] <= a[2*k+2]` for
## all `k`, counting elements from 0. The interesting property of a heap is that
## `a[0]` is always its smallest element.
##
## Basic usage
## -----------
##
var heap = initHeapQueue[int]()
heap.push(8)
heap.push(2)
heap.push(5)
# The first element is the lowest element
assert heap[0] == 2
# Remove and return the lowest element
assert heap.pop() == 2
# The lowest element remaining is 5
assert heap[0] == 5
runnableExamples:
var heap = initHeapQueue[int]()
heap.push(8)
heap.push(2)
heap.push(5)
# The first element is the lowest element
assert heap[0] == 2
# Remove and return the lowest element
assert heap.pop() == 2
# The lowest element remaining is 5
assert heap[0] == 5
Usage with custom object
------------------------
To use a `HeapQueue` with a custom object, the `<` operator must be
implemented.
## Usage with custom object
## ------------------------
## To use a `HeapQueue` with a custom object, the `<` operator must be
## implemented.
.. code-block:: Nim
import heapqueue
runnableExamples:
type Job = object
priority: int
type Job = object
priority: int
proc `<`(a, b: Job): bool = a.priority < b.priority
proc `<`(a, b: Job): bool = a.priority < b.priority
var jobs = initHeapQueue[Job]()
jobs.push(Job(priority: 1))
jobs.push(Job(priority: 2))
var jobs = initHeapQueue[Job]()
jobs.push(Job(priority: 1))
jobs.push(Job(priority: 2))
assert jobs[0].priority == 1
assert jobs[0].priority == 1
]##
import std/private/since
type HeapQueue*[T] = object
@@ -135,6 +133,9 @@ proc toHeapQueue*[T](x: openArray[T]): HeapQueue[T] {.since: (1, 3).} =
proc pop*[T](heap: var HeapQueue[T]): T =
## Pops and returns the smallest item from `heap`,
## maintaining the heap invariant.
runnableExamples:
var heap = toHeapQueue([9, 5, 8])
assert heap.pop() == 5
let lastelt = heap.data.pop()
if heap.len > 0:
result = heap[0]
@@ -145,12 +146,22 @@ proc pop*[T](heap: var HeapQueue[T]): T =
proc find*[T](heap: HeapQueue[T], x: T): int {.since: (1, 3).} =
## Linear scan to find index of item ``x`` or -1 if not found.
runnableExamples:
var heap = toHeapQueue([9, 5, 8])
assert heap.find(5) == 0
assert heap.find(9) == 1
assert heap.find(777) == -1
result = -1
for i in 0 ..< heap.len:
if heap[i] == x: return i
proc del*[T](heap: var HeapQueue[T], index: Natural) =
## Removes the element at `index` from `heap`, maintaining the heap invariant.
runnableExamples:
var heap = toHeapQueue([9, 5, 8])
heap.del(1)
assert heap[0] == 5
assert heap[1] == 8
swap(heap.data[^1], heap.data[index])
let newLen = heap.len - 1
heap.data.setLen(newLen)
@@ -163,16 +174,28 @@ proc replace*[T](heap: var HeapQueue[T], item: T): T =
## more appropriate when using a fixed-size heap. Note that the value
## returned may be larger than item! That constrains reasonable uses of
## this routine unless written as part of a conditional replacement:
##
## .. code-block:: nim
## if item > heap[0]:
## item = replace(heap, item)
runnableExamples:
var heap = initHeapQueue[int]()
heap.push(5)
heap.push(12)
assert heap.replace(6) == 5
assert heap.len == 2
assert heap[0] == 6
assert heap.replace(4) == 6
result = heap[0]
heap.data[0] = item
siftup(heap, 0)
proc pushpop*[T](heap: var HeapQueue[T], item: T): T =
## Fast version of a push followed by a pop.
runnableExamples:
var heap = initHeapQueue[int]()
heap.push(5)
heap.push(12)
assert heap.pushpop(6) == 5
assert heap.len == 2
assert heap[0] == 6
assert heap.pushpop(4) == 4
result = item
if heap.len > 0 and heapCmp(heap.data[0], item):
swap(result, heap.data[0])