kth order statistic
A worst-case O(n) algorithm to find the kth largest element in a list:
(define (quickselect alist k)
;; Divide the list into two:
;; elements greater and lesser than
;; the median.
(let* ((x (pick-mid alist))
(lt (lesser x alist))
(gt (greater x alist))
(gt-len (length gt)))
(cond ((<= k gt-len)
;; kth largest must be in gt
(quickselect gt k))
((> k (+ gt-len 1))
(quickselect lt (- k gt-len 1)))
(else x))))A sample run:
(define a '(10 3 5 8 20 90)) (printf "~a~n" (quickselect a 5)) ;; => 5 (printf "~a~n" (quickselect a 1)) ;; => 90 (printf "~a~n" (quickselect a 4)) ;; => 8 (printf "~a~n" (quickselect a 3)) ;; => 10 (printf "~a~n" (quickselect a 2)) ;; => 20
The helper functions used by quickselect:
(define (lesser x alist) (filter (lambda (a) (< a x)) alist)) (define (greater x alist) (filter (lambda (a) (> a x)) alist)) (define (pick-mid alist) (list-ref alist (round (/ (length alist) 2))))