5

次のように、Lisp (Scheme) で純粋に機能的なキューを開発しました。

;Internal functions
(define (delay-cons x s)
   (cons x (lambda () s)))
(define (delay-car s)
  (car s))
(define (delay-cdr s)
  ((cdr s)))

(define (delay-append s t)
  (if (null? s)
      t
      (delay-cons (delay-car s) (delay-append (delay-cdr s) t))))

;API
(define (enqueue x q) (delay-append q (delay-cons x empty)))
(define dequeue delay-cdr)
(define peek delay-car)
(define empty '())
(define empty? null?)

delay-cons は cons に似ていますが、末尾をクロージャでラップすることにより、末尾の評価を一時停止します。同様に、delay-append (delay-append st) は、t を末尾の再帰的な中断によって s に追加します。

したがって、各エンキューはクロージャの 1 つのレイヤーをラップして O(1) にし、各ピークは単純に値を取得して O(1) にし、各デキューは 1 つのクロージャを取得して評価し、O(1) にします。

これは他では見たことがありません。たとえば、Okasaki の Purely Functional Data Structures では、最も単純なキューは Banker's Queue であり、これはこれよりもはるかに複雑で、O(1) のエンキュー、ピーク、およびデキューのみを償却しています。これは、私の推論に誤りがあるのではないかと疑っています。

このデータ構造は健全ですか?どこかにそれに対する参照はありますか?

編集: delay-cons は、ここで delay-append で使用するのは間違っています。マクロのような関数を使用しようとしています (Will Ness に感謝します)。

を使って修正してみました

(define (delay-append s t)
  (if (null? s)
      t
      (cons (delay-car s) (lambda () (delay-append (delay-cdr s) t)))))

しかし、これは API では機能しません。

4

1 に答える 1