From afb8b69c0a61fbc821cd3ce014c017a3523bd3d2 Mon Sep 17 00:00:00 2001 From: flywind <43030857+xflywind@users.noreply.github.com> Date: Tue, 24 Nov 2020 21:29:34 +0800 Subject: [PATCH] improve document for heapqueue (#16107) --- lib/pure/collections/heapqueue.nim | 103 ++++++++++++++++++----------- 1 file changed, 63 insertions(+), 40 deletions(-) diff --git a/lib/pure/collections/heapqueue.nim b/lib/pure/collections/heapqueue.nim index 244ccbbeea..00e7a3b9d0 100644 --- a/lib/pure/collections/heapqueue.nim +++ b/lib/pure/collections/heapqueue.nim @@ -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`_ - that can be used as a - `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`_ +## that can be used as a +## `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])