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))))