queue.body.scm 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. ;;;
  2. ;;; Very simple queues implemented in terms of lists
  3. ;;;
  4. ;;; Copyright 2016 Jason K. MacDuffie
  5. ;;; License: GPLv3+
  6. ;;;
  7. ;; All procedures are O(1) except constructors which are linear
  8. (define-record-type <queue>
  9. (make-queue sz front back)
  10. queue?
  11. (sz queue-length set-size!)
  12. (front get-front set-front!)
  13. (back get-back set-back!))
  14. (define (last-pair l)
  15. (let loop ((a l)
  16. (b (cdr l)))
  17. (if (pair? b)
  18. (loop b (cdr b))
  19. a)))
  20. (define (queue-empty? q)
  21. (= (queue-length q) 0))
  22. (define (queue-front q)
  23. (if (queue-empty? q)
  24. (error "queue-front" "Referencing an empty queue")
  25. (car (get-front q))))
  26. (define (queue-back q)
  27. (if (queue-empty? q)
  28. (error "queue-back" "Referencing an empty queue")
  29. (car (get-back q))))
  30. (define (queue-add! q val)
  31. (define l (list val))
  32. (if (queue-empty? q)
  33. (set-front! q l)
  34. (set-cdr! (get-back q) l))
  35. (set-back! q l)
  36. (set-size! q (+ (queue-length q) 1)))
  37. (define (queue-add-front! q val)
  38. ;; It is also an O(1) operation to add to the front, so
  39. ;; we might as well provide this procedure.
  40. (if (queue-empty? q)
  41. (queue-add! q val)
  42. (begin
  43. (set-front! q (cons val (get-front q)))
  44. (set-size! q (+ (queue-length q) 1)))))
  45. (define (queue-remove! q)
  46. (define a (queue-front q))
  47. (set-front! q (cdr (get-front q)))
  48. (set-size! q (- (queue-length q) 1))
  49. a)
  50. (define (list->queue l)
  51. (apply queue l))
  52. (define (queue->list q)
  53. (list-copy (get-front q)))
  54. (define (queue . l)
  55. (make-queue (length l) l (if (null? l)
  56. '(0)
  57. (last-pair l))))