#lang racket
(require racket/mpair)
;; queue implementation from book
(define (front-ptr queue) (mcar queue))
(define (rear-ptr queue) (mcdr queue))
(define (set-front-ptr! queue item) (set-mcar! queue item))
(define (set-rear-ptr! queue item) (set-mcdr! queue item))
(define (empty-queue? queue) (null? (front-ptr queue)))
(define (make-queue) (mcons '() '()))
(define (front-queue queue)
(if (empty-queue? queue)
(error "FRONT called with an empty queue" queue)
(mcar (front-ptr queue))))
(define (insert-queue! queue item)
(define new-pair (mcons item '()))
(cond [(empty-queue? queue)
(set-front-ptr! queue new-pair)
(set-rear-ptr! queue new-pair)
queue]
[else
(set-mcdr! (rear-ptr queue) new-pair)
(set-rear-ptr! queue new-pair)
queue]))
(define (delete-queue! queue)
(cond [(empty-queue? queue)
(error "DELETE! called with an empty queue" queue)]
[else
(set-front-ptr! queue (mcdr (front-ptr queue)))
queue]))
;;;;;;;;;;
;; 3.21 ;;
;;;;;;;;;;
;; delete-queue! only changes the front pointer; it does not affect the rear
;; pointer. The rear pointer is only changed when we insert an element.
(define (print-queue queue)
(for ([item (front-ptr queue)])
(printf "~a " item))
(printf "~n"))
;; tests
(define q (make-queue))
(insert-queue! q 'a)
;; (mcons (mcons 'a '()) (mcons 'a '()))
(insert-queue! q 'b)
;; (mcons (mcons 'a (mcons 'b '())) (mcons 'b '()))
(print-queue q)
;; a b
(front-queue q)
;; 'a
(delete-queue! q)
;; (mcons (mcons 'b '()) (mcons 'b '()))
(print-queue q)
;; b
(delete-queue! q)
;; (mcons '() (mcons 'b '()))
(empty-queue? q)
;; #t
q
;; (mcons '() (mcons 'b '()))
(print-queue q)
;;
;;;;;;;;;;
;; 3.22 ;;
;;;;;;;;;;
(define (make-procedural-queue)
; representation details
(define front-ptr '())
(define rear-ptr '())
(define (set-front-ptr! item) (set! front-ptr item))
(define (set-rear-ptr! item) (set! rear-ptr item))
; selectors
(define (empty-queue?) (null? front-ptr))
(define (front-queue)
(if (empty-queue?)
(error "FRONT called with an empty queue")
(mcar front-ptr)))
; mutators
(define (insert-queue! item)
(define new-pair (mcons item '()))
(cond [(empty-queue?)
(set-front-ptr! new-pair)
(set-rear-ptr! new-pair)
(mcons front-ptr rear-ptr)]
[else
(set-mcdr! rear-ptr new-pair)
(set-rear-ptr! new-pair)
(mcons front-ptr rear-ptr)]))
(define (delete-queue!)
(cond [(empty-queue?)
(error "DELETE! called with an empty queue")]
[else
(set-front-ptr! (mcdr front-ptr))
(mcons front-ptr rear-ptr)]))
; display
(define (print-queue)
(for ([item front-ptr])
(printf "~a " item))
(printf "~n"))
; the queue procedure
(define (dispatch m)
(cond [(eq? m 'empty-queue?) (empty-queue?)]
[(eq? m 'front-queue) (front-queue)]
[(eq? m 'insert-queue!) insert-queue!]
[(eq? m 'delete-queue!) (delete-queue!)]
[(eq? m 'print-queue) (print-queue)]))
dispatch)
;; tests
(define q1 (make-procedural-queue))
((q1 'insert-queue!) 'a)
;; (mcons (mcons 'a '()) (mcons 'a '()))
((q1 'insert-queue!) 'b)
;; (mcons (mcons 'a (mcons 'b '())) (mcons 'b '()))
(q1 'print-queue)
;; a b
(q1 'front-queue)
;; 'a
(q1 'delete-queue!)
;; (mcons (mcons 'b '()) (mcons 'b '()))
(q1 'print-queue)
;; b
(q1 'delete-queue!)
;; (mcons '() (mcons 'b '()))
(q1 'empty-queue?)
;; #t
(q1 'print-queue)
;;
;;;;;;;;;;
;; 3.23 ;;
;;;;;;;;;;
;; To get O(1) deque operations, we need a doubly-linked list. To get a
;; doubly-linked list, I used triples (mcons x (mcons p1 p2)) where x is the
;; current list element, p1 is a pointer to the previous triple, and p2 is a
;; pointer to the next triple.
;; representation details
(define (front-deque-ptr deque) (mcar deque))
(define (rear-deque-ptr deque) (mcdr deque))
(define (set-front-deque-ptr! deque item) (set-mcar! deque item))
(define (set-rear-deque-ptr! deque item) (set-mcdr! deque item))
;; triples
(define (make-triple item) (mcons item (mcons empty empty)))
(define (previous-ptr triple) (mcar (mcdr triple)))
(define (next-ptr triple) (mcdr (mcdr triple)))
(define (set-previous-ptr! triple new-triple)
(set-mcar! (mcdr triple) new-triple))
(define (set-next-ptr! triple new-triple)
(set-mcdr! (mcdr triple) new-triple))
;; constructor
(define (make-deque) (mcons empty empty))
;; predicate
(define (empty-deque? deque) (empty? (front-deque-ptr deque)))
;; selectors
(define (front-deque deque)
(if (empty-deque? deque)
(error "FRONT called with an empty deque" deque)
(mcar (front-deque-ptr deque))))
(define (rear-deque deque)
(if (empty-deque? deque)
(error "REAR called with an empty deque" deque)
(mcar (rear-deque-ptr deque))))
;; mutators
(define (front-insert-deque! deque item)
(define new-triple (make-triple item))
(cond [(empty-deque? deque)
(set-front-deque-ptr! deque new-triple)
(set-rear-deque-ptr! deque new-triple)
deque]
[else
(set-next-ptr! new-triple (front-deque-ptr deque))
(set-previous-ptr! (front-deque-ptr deque) new-triple)
(set-front-deque-ptr! deque new-triple)
deque]))
(define (rear-insert-deque! deque item)
(define new-triple (make-triple item))
(cond [(empty-deque? deque)
(set-front-deque-ptr! deque new-triple)
(set-rear-deque-ptr! deque new-triple)
deque]
[else
(set-previous-ptr! new-triple (rear-deque-ptr deque))
(set-next-ptr! (rear-deque-ptr deque) new-triple)
(set-rear-deque-ptr! deque new-triple)
deque]))
(define (front-delete-deque! deque)
(cond [(empty-deque? deque)
(error "FRONT-DELETE! called with an empty deque" deque)]
[(eq? (front-deque-ptr deque) (rear-deque-ptr deque))
(set-front-deque-ptr! deque empty)
(set-rear-deque-ptr! deque empty)
deque]
[else
(set-previous-ptr! (next-ptr (front-deque-ptr deque)) empty)
(set-front-deque-ptr! deque (next-ptr (front-deque-ptr deque)))
deque]))
(define (rear-delete-deque! deque)
(cond [(empty-deque? deque)
(error "REAR-DELETE! called with an empty deque" deque)]
[(eq? (front-deque-ptr deque) (rear-deque-ptr deque))
(set-front-deque-ptr! deque empty)
(set-rear-deque-ptr! deque empty)
deque]
[else
(set-next-ptr! (previous-ptr (rear-deque-ptr deque)) empty)
(set-rear-deque-ptr! deque (previous-ptr (rear-deque-ptr deque)))
deque]))
(define (print-deque deque)
(define (loop triple)
(printf "~a " (mcar triple))
(define next-triple (next-ptr triple))
(if (not (empty? next-triple))
(loop next-triple)
(printf "~n")))
(if (empty-deque? deque)
(printf "~n")
(loop (front-deque-ptr deque))))
;; tests
(define d (make-deque))
(print-deque (front-insert-deque! d 'a))
;; a
(print-deque (front-insert-deque! d 'b))
;; b a
(print-deque (rear-insert-deque! d 'c))
;; b a c
(front-deque d)
;; 'b
(rear-deque d)
;; 'c
(print-deque (rear-delete-deque! d))
;; b a
(print-deque (front-delete-deque! d))
;; a
(print-deque (rear-delete-deque! d))
;;
(empty-deque? d)
;; #t
Comments
0 B
|👍
/👎
0 B
|👍
/👎