racket/collects/data/scribblings/skip-list.scrbl
2011-04-25 22:18:00 -06:00

174 lines
6.0 KiB
Racket

#lang scribble/manual
@(require scribble/eval
(for-label data/skip-list
data/order
racket/contract
racket/dict
racket/base))
@title[#:tag "skip-list"]{Skip Lists}
@(define the-eval (make-base-eval))
@(the-eval '(require racket/dict data/order data/skip-list))
@defmodule[data/skip-list]
@author[@author+email["Ryan Culpepper" "ryanc@racket-lang.org"]]
Skip lists are a simple, efficient data structure for mutable
dictionaries with totally ordered keys. They were described in the
paper ``Skip Lists: A Probabilistic Alternative to Balanced Trees'' by
William Pugh in Communications of the ACM, June 1990, 33(6) pp668-676.
A skip-list is an ordered dictionary (@racket[dict?] and
@racket[ordered-dict?]). It also supports extensions of the dictionary
interface for iterator-based search and mutation.
@defproc[(make-skip-list [ord order? datum-order]
[#:key-contract key-contract contract? any/c]
[#:value-contract value-contract contract? any/c])
skip-list?]{
Makes a new empty skip-list. The skip-list uses @racket[ord] to order
keys; in addition, the domain contract of @racket[ord] is combined
with @racket[key-contract] to check keys.
@examples[#:eval the-eval
(define skip-list (make-skip-list real-order))
(skip-list-set! skip-list 3 'apple)
(skip-list-set! skip-list 6 'cherry)
(dict-map skip-list list)
(skip-list-ref skip-list 3)
(skip-list-remove! skip-list 6)
(skip-list-count skip-list)
]
}
@defproc[(make-adjustable-skip-list
[#:key-contract key-contract contract? any/c]
[#:value-contract value-contract contract? any/c])
adjustable-skip-list?]{
Makes a new empty skip-list that permits only exact integers as keys
(in addition to any constraints imposed by @racket[key-contract]). The
resulting skip-list answers true to @racket[adjustable-skip-list?]
and supports key adjustment.
}
@defproc[(skip-list? [v any/c]) boolean?]{
Returns @racket[#t] if @racket[v] is a skip-list, @racket[#f]
otherwise.
}
@defproc[(adjustable-skip-list? [v any/c]) boolean?]{
Returns @racket[#t] if @racket[v] is a skip-list that supports key
adjustment; see @racket[skip-list-contract!] and
@racket[skip-list-expand!].
}
@deftogether[[
@defproc[(skip-list-ref [skip-list skip-list?]
[key any/c]
[default any/c (lambda () (error ....))])
any/c]
@defproc[(skip-list-set! [skip-list skip-list?]
[key any/c]
[value any/c])
void?]
@defproc[(skip-list-remove! [skip-list skip-list?]
[key any/c])
void?]
@defproc[(skip-list-count [skip-list skip-list?])
exact-nonnegative-integer?]
@defproc[(skip-list-iterate-first [skip-list skip-list?])
(or/c skip-list-iter? #f)]
@defproc[(skip-list-iterate-next [skip-list skip-list?]
[iter skip-list-iter?])
(or/c skip-list-iter? #f)]
@defproc[(skip-list-iterate-key [skip-list skip-list?]
[iter skip-list-iter?])
any/c]
@defproc[(skip-list-iterate-value [skip-list skip-list?]
[iter skip-list-iter?])
any/c]]]{
Implementations of @racket[dict-ref], @racket[dict-set!],
@racket[dict-remove!], @racket[dict-count],
@racket[dict-iterate-first], @racket[dict-iterate-next],
@racket[dict-iterate-key], and @racket[dict-iterate-value],
respectively.
}
@defproc[(skip-list-remove-range! [skip-list skip-list?]
[from any/c]
[to any/c])
void?]{
Removes all keys in [@racket[from], @racket[to]); that is, all keys
greater than or equal to @racket[from] and less than @racket[to].
}
@defproc[(skip-list-contract! [skip-list adjustable-skip-list?]
[from exact-integer?]
[to exact-integer?])
void?]{
Like @racket[skip-list-remove-range!], but also decreases the value
of all keys greater than or equal to @racket[to] by @racket[(- to
from)].
This operation takes time proportional to the number of elements with
keys greater than or equal to @racket[to].
}
@defproc[(skip-list-expand! [skip-list adjustable-skip-list?]
[from exact-integer?]
[to exact-integer?])
void?]{
Increases the value of all keys greater than or equal to @racket[from]
by @racket[(- to from)].
This operation takes time proportional to the number of elements with
keys greater than or equal to @racket[from].
}
@deftogether[[
@defproc[(skip-list-iterate-least/>? [skip-list skip-list?]
[key any/c])
(or/c skip-list-iter? #f)]
@defproc[(skip-list-iterate-least/>=? [skip-list skip-list?]
[key any/c])
(or/c skip-list-iter? #f)]
@defproc[(skip-list-iterate-greatest/<? [skip-list skip-list?]
[key any/c])
(or/c skip-list-iter? #f)]
@defproc[(skip-list-iterate-greatest/<=? [skip-list skip-list?]
[key any/c])
(or/c skip-list-iter? #f)]
@defproc[(skip-list-iterate-least [skip-list skip-list?])
(or/c skip-list-iter? #f)]
@defproc[(skip-list-iterate-greatest [skip-list skip-list?])
(or/c skip-list-iter? #f)]]]{
Implementations of @racket[dict-iterate-least],
@racket[dict-iterate-greatest], @racket[dict-iterate-least/>?],
@racket[dict-iterate-least/>=?], @racket[dict-iterate-greatest/<?],
@racket[dict-iterate-greatest/<=?], @racket[dict-iterate-least], and
@racket[dict-iterate-greatest], respectively.
}
@defproc[(skip-list-iter? [v any/c]) boolean?]{
Returns @racket[#t] if @racket[v] represents a position in a
skip-list, @racket[#f] otherwise.
}
@defproc[(skip-list->list [skip-list skip-list?]) (listof pair?)]{
Returns an association list with the keys and values of
@racket[skip-list], in order.
}