« log |Main| 日記 »

« Schemeで破壊的クイックソート | Scheme/Lisp | Pythonで87文字でCollatz角谷問題の(以下略 »

Schemeで双方向リスト

今日の帰宅車内ハック。といっても武蔵野線は混んでいて座れなかったのでりんかい線の中だけなのですけど。先日作った双方向リストに見やすい表示機能をつけて、Dancing Linksのremoveとrestoreを実装しました。 肝心の双方向リストのソースコードがなくなっていてうちひしがれかけたのですけど、改めて書いてみるとすんなり書けてしまいました。やっぱり最初に作るときが一番大変ですが、一度できるとできたときの「Aha!」によって重要なところは脳に刻み込まれるのでソースがなくなってももう一度作ることができるわけです。そんなことはどうでもいいか。

(define (doublyLinkedList x prev)
  (if (null? x)
      ()
      (let ((c (cons (car x) (cons () prev))))
        (set-car! (cdr c) (doublyLinkedList (cdr x) c))
        c)))

(define dl (doublyLinkedList '(1 2 3 4 5) ()))
  
(define (getPrev x)
  (cdr (cdr x)))

(define (getNext x)
  (car (cdr x)))

(define (print x)
  (define (_print x)
    (if (null? x)
        (display ")")
        (begin
          (display " ")
          (display (car x))
          (_print (getNext x)))))
  (display "(")
  (display (car x))
  (_print (getNext x)))

(print dl) ;-> (1 2 3 4 5)
(print (getNext dl)) ;-> (2 3 4 5)

(define (getNth x i)
  (if (= i 0)
      x
      (getNth (getNext x) (- i 1))))

(define three (getNth dl 2))
(print three) ; -> (3 4 5)

(define (setRight x y)
  (set-car! (cdr x) y))

(define (setLeft x y)
  (set-cdr! (cdr x) y))

(define (remove x)
  (let 
      ((right (getNext x))
       (left (getPrev x)))
    (setRight left right)
    (setLeft right left)))

(remove three)
(print dl) ;-> (1 2 4 5)

(define (restore x)
  (let
      ((right (getNext x))
       (left (getPrev x)))
    (setRight left x)
    (setLeft right x)))

(restore three)
(print dl) ;-> (1 2 3 4 5)

トラックバック(Trackback)

Trackback URL: http://www.nishiohirokazu.org/mt/mt-tb.cgi/176

ご意見・ご感想をお送りください(フィードバック)

(フィードバックはメールで送信され、基本的に表示されませんが、内容によっては公開させていただくこともございます。ご了承ください。Your comment doesn't appear the page immediately. If the comment has value to other people, it will be put on the page or subsequent entries. Thank you.)

上の情報は、いずれも未記入でかまいません。 All of above questions are optional.