;;; File: ;;; sorting.scm ;;; Author: ;;; Samuel A. Rebelsky ;;; The denizens of CSC153 2004S ;;; Version: ;;; 0.1 of March 2004 ;;; Summary: ;;; Some fun stuff to get us experience sorting ;;; Contents: ;;; (bubble-sort-numbers! vec) - Sort a vector of numbers with the ;;; beautiful, elegant, and fast bubble-sort algorithm ;;; (selection-sort-numbers! vec) - Sort a vector of numbers with the ;;; ugly, inelegant, and significantly slow selection-sort algorithm. (load "timing-sum.scm") ; Gets me the wonderful random-list procedure (define random-vector (lambda (length) (list->vector (random-list length)))) (define selection-sort-numbers! (lambda (vec) (let kernel ((pos (- (vector-length vec) 1))) (if (> pos 0) (begin (swap! vec pos (position-of-largest vec 0 pos)) (kernel (- pos 1))))))) ;;; Purpose: ;;; Find the position of the largest element in the subvector ;;; [start ... end] ;;; Pstrategies: ;;; Go through the elements one by one. ;;; Have an extra variable that keeps track of the best so far. (define position-of-largest (lambda (vec start end) (let kernel ((best start) (pos start)) (cond ((> pos end) best) ((> (vector-ref vec pos) (vector-ref vec best)) (kernel pos (+ pos 1))) (else (kernel best (+ pos 1))))))) ; Look! There are six P's here. You just can't see them yet. (define swap! (lambda (vec pos1 pos2) (let ((tmp (vector-ref vec pos1))) (vector-set! vec pos1 (vector-ref vec pos2)) (vector-set! vec pos2 tmp)))) ;;; Process: ;;; Repeatedly swap numbers that are out of order ;;; Outer loop: For pos := final-pos down to starting pos ;;; Inner loop: For step := starting-pos to pos-1 ;;; Inner step: swap stuff out of order (define bubble-sort-numbers! (lambda (vec) (letrec ((inner (lambda (step max) (if (< step max) (begin (if (> (vector-ref vec step) (vector-ref vec (+ step 1))) (swap! vec step (+ step 1))) (inner (+ step 1) max)))))) (let outer ((pos (- (vector-length vec) 1))) (if (> pos 0) (begin (inner 0 pos) (outer (- pos 1))))))))