sicp(sicp37)m3.23

delete-rear-queue!がなければ、次の値だけ保持するようなデータ構造でO(1)の処理ができる。
(delete-rear-queue!だけはO(N)になってしまう。)

(define (make-queue)
  (let ((front-ptr '())
        (rear-ptr '()))
    (define (set-front-ptr! item) (set! front-ptr  item))
    (define (set-rear-ptr! item) (set! rear-ptr item))
    (define (empty-queue?) (null? front-ptr))
    (define (make-element entry)
      (cons entry (cons '() '())))
    (define (show)
      (define (loop item)
        (if (null? item)
            '()
            (begin
              (display (car item))
              (display " ->")
              (loop (cddr item)))))
      (loop front-ptr))
    (define (front-queue queue)
      (if (empty-queue?)
          (error "FRONT called with an empty queue")
          (car front-ptr)))
    (define (insert-front-queue! item)
      (let ((new-element (make-element item)))
		        ;;(entry prev next)
        (cond ((empty-queue?)
               (set-front-ptr! new-element)
               (set-rear-ptr! new-element)
               (show))
              (else
               (set-cdr! (cdr new-element) front-ptr)
               (set-car! (cdr front-ptr) new-element)
               (set-front-ptr! new-element)
               (show)))))
    (define (insert-rear-queue! item)
      (let ((new-element (make-element item)))
        (cond ((empty-queue?)
               (set-front-ptr! new-element)
               (set-rear-ptr! new-element)
               (show))
              (else
               (set-car! (cdr new-element) rear-ptr)
               (set-cdr! (cdr rear-ptr) new-element)
               (set-rear-ptr!  new-element)
               (show)))))
    (define (delete-front-queue!)
      (cond ((empty-queue?)
             (error "DELTE! called with an empty queue"))
            (else
             (set-front-ptr! (cddr front-ptr))
             ;(set-car! (cdr front-ptr) '())
             (show))))
    (define (delete-rear-queue!)
      (cond ((empty-queue?)
             (error "DELTE! called with an empty queue"))
            (else
             (set-rear-ptr! (cadr rear-ptr))
                 (if (null? rear-ptr)
                     (set-front-ptr! '())
                     (set-cdr! (cdr rear-ptr) '()))
             (show))))
    (define (dispatch m)
      (let ((methods (list
                      (cons 'empty-queue? empty-queue?)
                      (cons 'front-queue front-queue)
                      (cons 'insert-front-queue! insert-front-queue!)
                      (cons 'insert-rear-queue! insert-rear-queue!)
                      (cons 'delete-front-queue! delete-front-queue!)
                      (cons 'delete-rear-queue! delete-rear-queue!))))
        (define (loop methods)
          (cond ((null? methods)
                 (error "this method is not found " m))
                ((eq? m (caar methods))
;;                  (print (caar methods) " is called.")
                 (cdar methods))
                (else (loop (cdr methods)))))
        (loop methods)))
    dispatch))
(define q (make-queue))
((q 'insert-front-queue!) 'a)
((q 'insert-rear-queue!) 'b)
((q 'insert-front-queue!) 'c)
((q 'insert-rear-queue!) 'd)
((q 'delete-front-queue!))
((q 'delete-rear-queue!))
	;; 55:user> => q
	;; 56:user> a ->=> ()
	;; 57:user> a ->b ->=> ()
	;; 58:user> c ->a ->b ->=> ()
	;; 59:user> c ->a ->b ->d ->=> ()
	;; 60:user> a ->b ->d ->=> ()
	;; 61:user> a ->b ->=> ()