home *** CD-ROM | disk | FTP | other *** search
- ;;; -*- Scheme -*-
-
- (declare (usual-integrations))
-
- (let-syntax ((define-integrable
- (macro (params . body)
- `(begin
- (declare (integrate-operator ,(car params)))
- (define ,(car params)
- (named-lambda ,params
- (declare (integrate ,@(cdr params)))
- ,@body))))))
-
- (define (sort obj pred)
- (cond ((pair? obj)
- (vector->list (sort! (list->vector obj) pred)))
- ((vector? obj)
- (sort! (vector-copy obj) pred))
- ((null? obj)
- '())
- (else
- (error "sort: argument should be a list or a vector"))))
-
- (define (sort! vec pred)
- (define-integrable (exchange! i j)
- (let ((old (vector-ref vec i)))
- (vector-set! vec i (vector-ref vec j))
- (vector-set! vec j old)))
-
- (define (split a b)
- (cond ((= b (1+ a))
- (if (not (pred (vector-ref vec a)
- (vector-ref vec b)))
- (exchange! a b)))
- ((< a b)
- (let* ((middle (quotient (+ a b) 2))
- (val (vector-ref vec middle)))
-
- (define (split-1-end i j)
- (if (> i b)
- (begin
- (exchange! middle b)
- (split a (-1+ b)))
- (begin
- (split a j)
- (split i b))))
-
- (define (split-1 i j)
- (cond ((> i j)
- (split-1-end i j))
- ((pred (vector-ref vec i) val)
- (split-1 (1+ i) j))
- (else (split-2 i j))))
-
- (define (split-2-end i j)
- (if (< j a)
- (begin
- (exchange! a middle)
- (split (1+ a) b))
- (begin
- (split a j)
- (split i b))))
-
- (define (split-2 i j)
- (cond ((< j i)
- (split-2-end i j))
- ((pred val (vector-ref vec j))
- (split-2 i (-1+ j)))
- (else
- (exchange! i j)
- (split-1 (1+ i) (-1+ j)))))
-
- (split-1 a b)))))
-
- (if (not (vector? vec))
- (error "sort!: argument must be a vector" vec))
-
- (split 0 (-1+ (vector-length vec)))
- vec)
-
- ) ;; End of let-syntax