2022-05-06 16:01:59 +00:00
|
|
|
#lang sicp
|
|
|
|
|
|
|
|
(define (front-ptr deque) (car deque))
|
2022-05-09 13:40:54 +00:00
|
|
|
(define (rear-ptr deque) (cdr deque))
|
2022-05-06 16:01:59 +00:00
|
|
|
(define (set-front-ptr! deque item) (set-car! deque item))
|
2022-05-09 13:40:54 +00:00
|
|
|
(define (set-rear-ptr! deque item) (set-cdr! deque item))
|
|
|
|
|
|
|
|
(define (make-deque-item prev data next)
|
2022-05-09 21:13:08 +00:00
|
|
|
(list (lambda () prev) data next))
|
2022-05-09 13:40:54 +00:00
|
|
|
(define (item-prev item)
|
2022-05-09 21:13:08 +00:00
|
|
|
((car item)))
|
2022-05-09 13:40:54 +00:00
|
|
|
(define (item-data item)
|
|
|
|
(cadr item))
|
|
|
|
(define (item-next item)
|
|
|
|
(caddr item))
|
|
|
|
(define (item-set-prev! item prev)
|
2022-05-09 21:13:08 +00:00
|
|
|
(set-car! item (lambda () prev)))
|
2022-05-09 13:40:54 +00:00
|
|
|
(define (item-set-next! item next)
|
|
|
|
(set-cdr! (cdr item) (list next)))
|
2022-05-06 16:01:59 +00:00
|
|
|
|
|
|
|
(define (make-deque)
|
2022-05-09 13:40:54 +00:00
|
|
|
(cons '() '()))
|
2022-05-06 16:01:59 +00:00
|
|
|
|
|
|
|
(define (empty-deque? deque) (null? (front-ptr deque)))
|
|
|
|
|
2022-05-09 21:13:53 +00:00
|
|
|
(define (deque->list d)
|
|
|
|
(define (iter l)
|
|
|
|
(if (null? l)
|
|
|
|
'()
|
|
|
|
(cons (item-data l)
|
|
|
|
(iter (item-next l)))))
|
|
|
|
(iter (front-ptr d)))
|
|
|
|
|
2022-05-06 16:01:59 +00:00
|
|
|
(define (front-deque deque)
|
|
|
|
(if (empty-deque? deque)
|
|
|
|
(error "FRONT called with an empty deque" deque)
|
2022-05-09 13:40:54 +00:00
|
|
|
(item-data (front-ptr deque))))
|
2022-05-06 16:01:59 +00:00
|
|
|
|
|
|
|
(define (rear-deque deque)
|
|
|
|
(if (empty-deque? deque)
|
|
|
|
(error "REAR called with an empty deque" deque)
|
2022-05-09 13:40:54 +00:00
|
|
|
(item-data (rear-ptr deque))))
|
2022-05-06 16:01:59 +00:00
|
|
|
|
2022-05-09 13:40:54 +00:00
|
|
|
(define (front-insert! deque data)
|
|
|
|
(let* ((next (front-ptr deque))
|
|
|
|
(item (make-deque-item
|
|
|
|
'()
|
|
|
|
data
|
|
|
|
next)))
|
2022-05-06 16:01:59 +00:00
|
|
|
(cond ((empty-deque? deque)
|
2022-05-09 13:40:54 +00:00
|
|
|
(set-front-ptr! deque item)
|
|
|
|
(set-rear-ptr! deque item))
|
2022-05-06 16:01:59 +00:00
|
|
|
(else
|
2022-05-09 13:40:54 +00:00
|
|
|
(set-front-ptr! deque item)
|
|
|
|
(item-set-prev! next item)))))
|
|
|
|
|
|
|
|
(define (rear-insert! deque data)
|
|
|
|
(let* ((prev (rear-ptr deque))
|
|
|
|
(item (make-deque-item
|
|
|
|
prev
|
|
|
|
data
|
|
|
|
'())))
|
|
|
|
(cond ((empty-deque? deque)
|
|
|
|
(set-front-ptr! deque item)
|
|
|
|
(set-rear-ptr! deque item))
|
|
|
|
(else
|
|
|
|
(set-rear-ptr! deque item)
|
|
|
|
(item-set-next! prev item)))))
|
|
|
|
|
2022-05-09 21:14:15 +00:00
|
|
|
;; When the front and rear-pointers are equal, the deque has one element.
|
|
|
|
;; This is a special case to prevent just one of the pointers being set to
|
|
|
|
;; null when deleting the last element.
|
|
|
|
|
2022-05-06 16:01:59 +00:00
|
|
|
(define (front-delete! deque)
|
2022-05-09 13:40:54 +00:00
|
|
|
(cond ((empty-deque? deque)
|
|
|
|
(error "FRONT-DELETE! called with an empty deque" deque))
|
2022-05-09 21:14:15 +00:00
|
|
|
((eq? (front-ptr deque) (rear-ptr deque))
|
|
|
|
(set-front-ptr! deque '())
|
|
|
|
(set-rear-ptr! deque '()))
|
2022-05-09 13:40:54 +00:00
|
|
|
(else
|
|
|
|
(let ((front-item (front-ptr deque)))
|
2022-05-09 21:14:15 +00:00
|
|
|
(set-front-ptr! deque
|
|
|
|
(item-next front-item))
|
2022-05-09 13:40:54 +00:00
|
|
|
(if (not (null? front-item))
|
2022-05-10 16:14:44 +00:00
|
|
|
(item-set-prev! front-item '()))))))
|
2022-05-06 16:01:59 +00:00
|
|
|
|
|
|
|
(define (rear-delete! deque)
|
2022-05-09 13:40:54 +00:00
|
|
|
(cond ((empty-deque? deque)
|
|
|
|
(error "REAR-DELETE! called with an empty deque" deque))
|
2022-05-09 21:14:15 +00:00
|
|
|
((eq? (front-ptr deque) (rear-ptr deque))
|
|
|
|
(set-front-ptr! deque '())
|
|
|
|
(set-rear-ptr! deque '()))
|
2022-05-09 13:40:54 +00:00
|
|
|
(else
|
|
|
|
(set-rear-ptr! deque
|
|
|
|
(item-prev (rear-ptr deque)))
|
2022-05-09 21:14:15 +00:00
|
|
|
(if (not (null? (rear-ptr deque)))
|
2022-05-10 16:14:44 +00:00
|
|
|
(item-set-next! (rear-ptr deque) '())))))
|
2022-05-06 16:01:59 +00:00
|
|
|
|
|
|
|
(define (print-deque deque)
|
2022-05-09 13:40:54 +00:00
|
|
|
(define (print-items items)
|
|
|
|
(if (not (null? items))
|
2022-05-10 16:14:44 +00:00
|
|
|
(begin
|
|
|
|
(display (item-data items))
|
|
|
|
(print-items (item-next items)))))
|
2022-05-09 13:40:54 +00:00
|
|
|
(display "(")
|
|
|
|
(print-items (front-ptr deque))
|
|
|
|
(display ")")
|
2022-05-06 16:01:59 +00:00
|
|
|
(newline))
|
2022-05-09 13:40:54 +00:00
|
|
|
|
2022-05-10 16:15:26 +00:00
|
|
|
(#%require (only racket/base module+))
|
2022-05-09 13:40:54 +00:00
|
|
|
|
2022-05-10 16:15:26 +00:00
|
|
|
(module+ test
|
|
|
|
(#%require rackunit)
|
|
|
|
|
|
|
|
(test-begin
|
|
|
|
(define d (make-deque))
|
|
|
|
(check-equal? (deque->list d) '())
|
|
|
|
(front-insert! d 'a)
|
|
|
|
(check-equal? (deque->list d) '(a))
|
|
|
|
(rear-insert! d 'b)
|
|
|
|
(check-equal? (deque->list d) '(a b))
|
|
|
|
(rear-delete! d)
|
|
|
|
(check-equal? (deque->list d) '(a))
|
|
|
|
(rear-delete! d)
|
|
|
|
(check-equal? (deque->list d) '())
|
|
|
|
(rear-insert! d 'b)
|
|
|
|
(check-equal? (deque->list d) '(b))
|
|
|
|
(rear-insert! d 'b)
|
|
|
|
(check-equal? (deque->list d) '(b b))
|
|
|
|
(front-delete! d)
|
|
|
|
(check-equal? (deque->list d) '(b)))
|
|
|
|
)
|