Advertisement
timothy235

sicp-3-3-2-representing-queues

Feb 24th, 2017
165
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Racket 7.48 KB | None | 0 0
  1. #lang racket
  2. (require racket/mpair)
  3.  
  4. ;; queue implementation from book
  5.  
  6. (define (front-ptr queue) (mcar queue))
  7. (define (rear-ptr queue) (mcdr queue))
  8. (define (set-front-ptr! queue item) (set-mcar! queue item))
  9. (define (set-rear-ptr! queue item) (set-mcdr! queue item))
  10.  
  11. (define (empty-queue? queue) (null? (front-ptr queue)))
  12. (define (make-queue) (mcons '() '()))
  13.  
  14. (define (front-queue queue)
  15.   (if (empty-queue? queue)
  16.     (error "FRONT called with an empty queue" queue)
  17.     (mcar (front-ptr queue))))
  18.  
  19. (define (insert-queue! queue item)
  20.   (define new-pair (mcons item '()))
  21.   (cond [(empty-queue? queue)
  22.          (set-front-ptr! queue new-pair)
  23.          (set-rear-ptr! queue new-pair)
  24.          queue]
  25.         [else
  26.           (set-mcdr! (rear-ptr queue) new-pair)
  27.           (set-rear-ptr! queue new-pair)
  28.           queue]))
  29. (define (delete-queue! queue)
  30.   (cond [(empty-queue? queue)
  31.          (error "DELETE! called with an empty queue" queue)]
  32.         [else
  33.           (set-front-ptr! queue (mcdr (front-ptr queue)))
  34.           queue]))
  35.  
  36. ;;;;;;;;;;
  37. ;; 3.21 ;;
  38. ;;;;;;;;;;
  39.  
  40. ;; delete-queue! only changes the front pointer;  it does not affect the rear
  41. ;; pointer.  The rear pointer is only changed when we insert an element.
  42.  
  43. (define (print-queue queue)
  44.   (for ([item (front-ptr queue)])
  45.     (printf "~a " item))
  46.   (printf "~n"))
  47.  
  48. ;; tests
  49.  
  50. (define q (make-queue))
  51. (insert-queue! q 'a)
  52. ;; (mcons (mcons 'a '()) (mcons 'a '()))
  53. (insert-queue! q 'b)
  54. ;; (mcons (mcons 'a (mcons 'b '())) (mcons 'b '()))
  55. (print-queue q)
  56. ;; a b
  57. (front-queue q)
  58. ;; 'a
  59. (delete-queue! q)
  60. ;; (mcons (mcons 'b '()) (mcons 'b '()))
  61. (print-queue q)
  62. ;; b
  63. (delete-queue! q)
  64. ;; (mcons '() (mcons 'b '()))
  65. (empty-queue? q)
  66. ;; #t
  67. q
  68. ;; (mcons '() (mcons 'b '()))
  69. (print-queue q)
  70. ;;
  71.  
  72. ;;;;;;;;;;
  73. ;; 3.22 ;;
  74. ;;;;;;;;;;
  75.  
  76. (define (make-procedural-queue)
  77.   ; representation details
  78.   (define front-ptr '())
  79.   (define rear-ptr '())
  80.   (define (set-front-ptr! item) (set! front-ptr item))
  81.   (define (set-rear-ptr! item) (set! rear-ptr item))
  82.   ; selectors
  83.   (define (empty-queue?) (null? front-ptr))
  84.   (define (front-queue)
  85.     (if (empty-queue?)
  86.       (error "FRONT called with an empty queue")
  87.       (mcar front-ptr)))
  88.   ; mutators
  89.   (define (insert-queue! item)
  90.     (define new-pair (mcons item '()))
  91.     (cond [(empty-queue?)
  92.            (set-front-ptr! new-pair)
  93.            (set-rear-ptr! new-pair)
  94.            (mcons front-ptr rear-ptr)]
  95.           [else
  96.             (set-mcdr! rear-ptr new-pair)
  97.             (set-rear-ptr! new-pair)
  98.             (mcons front-ptr rear-ptr)]))
  99.   (define (delete-queue!)
  100.     (cond [(empty-queue?)
  101.            (error "DELETE! called with an empty queue")]
  102.           [else
  103.             (set-front-ptr! (mcdr front-ptr))
  104.             (mcons front-ptr rear-ptr)]))
  105.   ; display
  106.   (define (print-queue)
  107.     (for ([item front-ptr])
  108.       (printf "~a " item))
  109.     (printf "~n"))
  110.   ; the queue procedure
  111.   (define (dispatch m)
  112.     (cond [(eq? m 'empty-queue?) (empty-queue?)]
  113.           [(eq? m 'front-queue) (front-queue)]
  114.           [(eq? m 'insert-queue!) insert-queue!]
  115.           [(eq? m 'delete-queue!) (delete-queue!)]
  116.           [(eq? m 'print-queue) (print-queue)]))
  117.   dispatch)
  118.  
  119. ;; tests
  120.  
  121. (define q1 (make-procedural-queue))
  122. ((q1 'insert-queue!) 'a)
  123. ;; (mcons (mcons 'a '()) (mcons 'a '()))
  124. ((q1 'insert-queue!) 'b)
  125. ;; (mcons (mcons 'a (mcons 'b '())) (mcons 'b '()))
  126. (q1 'print-queue)
  127. ;; a b
  128. (q1 'front-queue)
  129. ;; 'a
  130. (q1 'delete-queue!)
  131. ;; (mcons (mcons 'b '()) (mcons 'b '()))
  132. (q1 'print-queue)
  133. ;; b
  134. (q1 'delete-queue!)
  135. ;; (mcons '() (mcons 'b '()))
  136. (q1 'empty-queue?)
  137. ;; #t
  138. (q1 'print-queue)
  139. ;;
  140.  
  141. ;;;;;;;;;;
  142. ;; 3.23 ;;
  143. ;;;;;;;;;;
  144.  
  145. ;; To get O(1) deque operations, we need a doubly-linked list.  To get a
  146. ;; doubly-linked list, I used triples (mcons x (mcons p1 p2)) where x is the
  147. ;; current list element, p1 is a pointer to the previous triple, and p2 is a
  148. ;; pointer to the next triple.
  149.  
  150. ;; representation details
  151. (define (front-deque-ptr deque) (mcar deque))
  152. (define (rear-deque-ptr deque) (mcdr deque))
  153. (define (set-front-deque-ptr! deque item) (set-mcar! deque item))
  154. (define (set-rear-deque-ptr! deque item) (set-mcdr! deque item))
  155.  
  156. ;; triples
  157. (define (make-triple item) (mcons item (mcons empty empty)))
  158. (define (previous-ptr triple) (mcar (mcdr triple)))
  159. (define (next-ptr triple) (mcdr (mcdr triple)))
  160. (define (set-previous-ptr! triple new-triple)
  161.   (set-mcar! (mcdr triple) new-triple))
  162. (define (set-next-ptr! triple new-triple)
  163.   (set-mcdr! (mcdr triple) new-triple))
  164.  
  165. ;; constructor
  166. (define (make-deque) (mcons empty empty))
  167. ;; predicate
  168. (define (empty-deque? deque) (empty? (front-deque-ptr deque)))
  169.  
  170. ;; selectors
  171. (define (front-deque deque)
  172.   (if (empty-deque? deque)
  173.     (error "FRONT called with an empty deque" deque)
  174.     (mcar (front-deque-ptr deque))))
  175. (define (rear-deque deque)
  176.   (if (empty-deque? deque)
  177.     (error "REAR called with an empty deque" deque)
  178.     (mcar (rear-deque-ptr deque))))
  179.  
  180. ;; mutators
  181. (define (front-insert-deque! deque item)
  182.   (define new-triple (make-triple item))
  183.   (cond [(empty-deque? deque)
  184.          (set-front-deque-ptr! deque new-triple)
  185.          (set-rear-deque-ptr! deque new-triple)
  186.          deque]
  187.         [else
  188.           (set-next-ptr! new-triple (front-deque-ptr deque))
  189.           (set-previous-ptr! (front-deque-ptr deque) new-triple)
  190.           (set-front-deque-ptr! deque new-triple)
  191.           deque]))
  192. (define (rear-insert-deque! deque item)
  193.   (define new-triple (make-triple item))
  194.   (cond [(empty-deque? deque)
  195.          (set-front-deque-ptr! deque new-triple)
  196.          (set-rear-deque-ptr! deque new-triple)
  197.          deque]
  198.         [else
  199.           (set-previous-ptr! new-triple (rear-deque-ptr deque))
  200.           (set-next-ptr! (rear-deque-ptr deque) new-triple)
  201.           (set-rear-deque-ptr! deque new-triple)
  202.           deque]))
  203. (define (front-delete-deque! deque)
  204.   (cond [(empty-deque? deque)
  205.          (error "FRONT-DELETE! called with an empty deque" deque)]
  206.         [(eq? (front-deque-ptr deque) (rear-deque-ptr deque))
  207.          (set-front-deque-ptr! deque empty)
  208.          (set-rear-deque-ptr! deque empty)
  209.          deque]
  210.         [else
  211.           (set-previous-ptr! (next-ptr (front-deque-ptr deque)) empty)
  212.           (set-front-deque-ptr! deque (next-ptr (front-deque-ptr deque)))
  213.           deque]))
  214. (define (rear-delete-deque! deque)
  215.   (cond [(empty-deque? deque)
  216.          (error "REAR-DELETE! called with an empty deque" deque)]
  217.         [(eq? (front-deque-ptr deque) (rear-deque-ptr deque))
  218.          (set-front-deque-ptr! deque empty)
  219.          (set-rear-deque-ptr! deque empty)
  220.          deque]
  221.         [else
  222.           (set-next-ptr! (previous-ptr (rear-deque-ptr deque)) empty)
  223.           (set-rear-deque-ptr! deque (previous-ptr (rear-deque-ptr deque)))
  224.           deque]))
  225.  
  226. (define (print-deque deque)
  227.   (define (loop triple)
  228.     (printf "~a " (mcar triple))
  229.     (define next-triple (next-ptr triple))
  230.     (if (not (empty? next-triple))
  231.       (loop next-triple)
  232.       (printf "~n")))
  233.   (if (empty-deque? deque)
  234.     (printf "~n")
  235.     (loop (front-deque-ptr deque))))
  236.  
  237. ;; tests
  238.  
  239. (define d (make-deque))
  240. (print-deque (front-insert-deque! d 'a))
  241. ;; a
  242. (print-deque (front-insert-deque! d 'b))
  243. ;; b a
  244. (print-deque (rear-insert-deque! d 'c))
  245. ;; b a c
  246. (front-deque d)
  247. ;; 'b
  248. (rear-deque d)
  249. ;; 'c
  250. (print-deque (rear-delete-deque! d))
  251. ;; b a
  252. (print-deque (front-delete-deque! d))
  253. ;; a
  254. (print-deque (rear-delete-deque! d))
  255. ;;
  256. (empty-deque? d)
  257. ;; #t
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement