From 28f1d4ff5d7508d27e938052115abc3817f60af7 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Sun, 16 Dec 2012 17:02:19 -0500 Subject: [PATCH] make argument order of heap-sort consistent with sort Old order is also accepted for backwards compatibility. --- collects/data/heap.rkt | 19 +++++++++++++++---- collects/data/scribblings/heap.scrbl | 27 ++++++++++++--------------- collects/tests/data/heap.rkt | 18 ++++++++++++++++++ 3 files changed, 45 insertions(+), 19 deletions(-) diff --git a/collects/data/heap.rkt b/collects/data/heap.rkt index 7cf3d81254..d3ebd95655 100644 --- a/collects/data/heap.rkt +++ b/collects/data/heap.rkt @@ -171,7 +171,18 @@ ;; -------- -(define (heap-sort! <=? v) +;; preferred order is (heap-sort vec <=?), but allow old order too +(define (heap-sort! x y) + (cond [(and (vector? x) (procedure? y)) + (heap-sort!* x y)] + [(and (vector? y) (procedure? x)) + (heap-sort!* y x)] + [else + (unless (vector? x) + (raise-argument-error 'heap-sort! "vector?" x)) + (raise-argument-error 'heap-sort! "procedure?" y)])) + +(define (heap-sort!* v <=?) ;; to get ascending order, need max-heap, so reverse comparison (define (>=? x y) (<=? y x)) (define size (vector-length v)) @@ -187,7 +198,7 @@ (match h [(heap vec size <=?) (let ([v (vector-copy vec 0 size)]) - (heap-sort! <=? v) + (heap-sort!* v <=?) v)])) ;; -------- @@ -205,7 +216,7 @@ [heap->vector (-> heap? vector?)] [heap-copy (-> heap? heap?)] - [heap-sort! (-> procedure? vector? void?)] - [in-heap (-> heap? sequence?)] [in-heap/consume! (-> heap? sequence?)]) + +(provide heap-sort!) diff --git a/collects/data/scribblings/heap.scrbl b/collects/data/scribblings/heap.scrbl index 8c3e04ead4..428dd1a92e 100644 --- a/collects/data/scribblings/heap.scrbl +++ b/collects/data/scribblings/heap.scrbl @@ -148,21 +148,6 @@ Makes a copy of heap @racket[h]. ] } - -@;{--------} - -@defproc[(heap-sort! [<=? (-> any/c any/c any/c)] [v (and/c vector? (not/c immutable?))]) void?]{ - -Sorts vector @racket[v] using the comparison function @racket[<=?]. - -@examples[#:eval the-eval - (define terms (vector "batch" "deal" "flock" "good deal" "hatful" "lot")) - (heap-sort! string<=? terms) - terms -] -} - - @defproc[(in-heap/consume! [heap heap?]) sequence?]{ Returns a sequence equivalent to @racket[heap], maintaining the heap's ordering. The heap is consumed in the process. Equivalent to repeated calling @@ -192,5 +177,17 @@ Equivalent to @racket[in-heap/consume!] except the heap is copied first. (heap-count h)] } +@;{--------} + +@defproc[(heap-sort! [v (and/c vector? (not/c immutable?))] [<=? (-> any/c any/c any/c)]) void?]{ + +Sorts vector @racket[v] using the comparison function @racket[<=?]. + +@examples[#:eval the-eval + (define terms (vector "batch" "deal" "flock" "good deal" "hatful" "lot")) + (heap-sort! terms string<=?) + terms +] +} @close-eval[the-eval] diff --git a/collects/tests/data/heap.rkt b/collects/tests/data/heap.rkt index 0c9aa3f897..9aace3aa74 100644 --- a/collects/tests/data/heap.rkt +++ b/collects/tests/data/heap.rkt @@ -84,3 +84,21 @@ [lst (for/list ([x (in-heap/consume! h)]) x)]) (heap-count h)) 0) + +(test-equal? "heap-sort" + (let ([v (vector 3 4 2 5 1)]) + (heap-sort! v <=) + v) + '#(1 2 3 4 5)) + +(test-equal? "heap-sort (old arg order)" + (let ([v (vector 3 4 2 5 1)]) + (heap-sort! <= v) + v) + '#(1 2 3 4 5)) + +(let* ([l (for/list ([i 1000]) (random 1000))] + [v (list->vector l)]) + (test-equal? "heap-sort (random)" + (begin (heap-sort! v <=) (vector->list v)) + (sort l <)))