racket/collects/unstable/scribblings/skip-list.scrbl

131 lines
4.4 KiB
Racket

#lang scribble/manual
@(require scribble/eval
"utils.rkt"
(for-label unstable/skip-list
racket/contract
racket/dict
racket/base))
@title[#:tag "skip-list"]{Skip Lists}
@(define the-eval (make-base-eval))
@(the-eval '(require unstable/skip-list))
@(the-eval '(require racket/dict))
@defmodule[unstable/skip-list]
@unstable[@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 a dictionary (@racket[dict?] from
@racketmodname[racket/dict]). It also supports extensions of the
dictionary interface for iterator-based search and mutation.
@defproc[(make-skip-list [=? (any/c any/c . -> . any/c)]
[<? (any/c any/c . -> . any/c)])
skip-list?]{
Makes a new empty skip-list. The skip-list uses @racket[=?] and @racket[<?] to order keys.
@examples[#:eval the-eval
(define skip-list (make-skip-list = <))
(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[(skip-list? [v any/c])
boolean?]{
Returns @racket[#t] if @racket[v] is a skip-list, @racket[#f]
otherwise.
}
@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.
}
@deftogether[[
@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?]
[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)]]]{
Return the position of, respectively, the greatest key less than
@racket[key], the greatest key less than or equal to @racket[key], the
least key greater than @racket[key], and the least key greater than or
equal to @racket[key].
}
@deftogether[[
@defproc[(skip-list-iterate-set-key! [skip-list skip-list?]
[iter skip-list-iter?]
[key any/c])
void?]
@defproc[(skip-list-iterate-set-value! [skip-list skip-list?]
[iter skip-list-iter?]
[value any/c])
void?]]]{
Set the key and value, respectively, at the position @racket[iter] in
@racket[skip-list].
@bold{Warning:} Changing a position's key to be less than its
predecessor's key or greater than its successor's key results in an
out-of-order skip-list, which may cause comparison-based operations to
behave incorrectly.
}
@defproc[(skip-list-iter? [v any/c])
boolean?]{
Returns @racket[#t] if @racket[v] represents a position in a
skip-list, @racket[#f] otherwise.
}