Representing Queues (pp.261-265)

キューを作ります。Θ(1)にするためにデータをためるリスト本体と、その前端(front-ptr)と後端(rear-ptr)を保持するpairがデータ構造になります。
が、しかしここでの実装は 空っぽの場合、というのを front-ptr が nilを指してる場合、としています。空の状態では実際のデータを溜めるリスト本体は無しで、insert時に空かどうかチェックして動作を変えてます。以下コード抜粋。

(define (insert-queue-sicp! queue item)
  (let ((new-pair (cons item '())))
    (cond ((empty-queue-sicp? queue)
	   (set-front-ptr! queue new-pair)
	   (set-rear-ptr! queue new-pair)
	   queue)
	  (else 
	   (set-cdr! (rear-ptr queue) new-pair)
	   (set-rear-ptr! queue new-pair)
	   queue))))

どうも趣味じゃない。(eq? front-ptr rear-ptr) だったら空、にしておけばinsertは以下にできる筈です。

(define (insert-queue! queue value)
  (let ((item (cons value '())))
    (set-cdr! (cdr queue) item)
    (set-cdr! queue item))
  queue)

というわけでそうやって書き換え。

(define (make-queue)
  (let ((queue-list (list 'dummy)))
    (cons queue-list queue-list)))

(define (empty-queue? queue)
  (eq? (front-ptr queue) (rear-ptr queue)))

(define (delete-queue! queue )
  (if (empty-queue? queue)
      (error "queue is empty!")
      (set-car! queue (cdar queue))))

(define (front-queue queue)
  (if (empty-queue? queue)
      (error "queue is empty!")
      (car (cdar queue))))

(define (pop-queue! queue)
  (let ((item (front-queue queue)))
    (delete-queue! queue)
    item))

常に1要素ゴミができてしまうのが問題なのですが、たいしたコストではないだろうと勝手に思いこむことにします。

あとで追記予定・・・