我正在尝试将队列实现为双向链接列表。 但是,当我尝试使第二个节点入队时,入队函数将进行无限递归,我似乎无法弄清楚是什么原因造成的。

(defstruct node
  value
  (next nil)
  (previous nil))



(defstruct (queue (:print-function print-queue))
  (first nil)
  (last nil))

(defun print-queue (queue s d)
  (do ((node (queue-first queue) (node-next node)))
      ((null node) (format s "~%"))
      (format s "~A " (node-value node))))

(defun enqueue (data queue)
  (let ((node (make-node :value data)))
    (if (null (queue-first queue))
        (setf (queue-first queue) node (queue-last queue) node)
        (setf (node-previous node) (queue-last queue)
              (node-next (queue-last queue)) node
              (queue-last queue) node))))

编辑:有问题的测试用例

(setf queue (make-queue))
(enqueue 3 queue)
(enqueue 4 queue) ; this call never terminates and blows up the stack

CLISP上的最后一条语句导致* -程序堆栈溢出。 重启

在SBCL上,它进入了无限循环,我必须退出SBCL

===============>>#1 票数:4 已采纳

好吧,您仍然没有真正查看错误。 ;-)

如果您使用SBCL:

0] backtrace

...
11898: (SB-KERNEL::%DEFAULT-STRUCTURE-PRETTY-PRINT #1=#S(NODE :VALUE 4 :NEXT NIL :PREVIOUS #S(NODE :VALUE 3 :NEXT #1# :PREVIOUS NIL)) #<SYNONYM-STREAM :SYMBOL SB-SYS:*STDOUT* {10001ACA23}>)
11899: ((LABELS SB-IMPL::HANDLE-IT :IN SB-KERNEL:OUTPUT-OBJECT) #<SYNONYM-STREAM :SYMBOL SB-SYS:*STDOUT* {10001ACA23}>)
11900: (PRIN1 #1=#S(NODE :VALUE 4 :NEXT NIL :PREVIOUS #S(NODE :VALUE 3 :NEXT #1# :PREVIOUS NIL)) NIL)
11901: (SB-IMPL::REPL-FUN NIL)
11902: ((LAMBDA NIL :IN SB-IMPL::TOPLEVEL-REPL))
11903: (SB-IMPL::%WITH-REBOUND-IO-SYNTAX #<CLOSURE (LAMBDA NIL :IN SB-IMPL::TOPLEVEL-REPL) {1002ACB00B}>)
11904: (SB-IMPL::TOPLEVEL-REPL NIL)
11905: (SB-IMPL::TOPLEVEL-INIT)
11906: ((FLET #:WITHOUT-INTERRUPTS-BODY-58 :IN SAVE-LISP-AND-DIE))
11907: ((LABELS SB-IMPL::RESTART-LISP :IN SAVE-LISP-AND-DIE))

这不是您的功能导致的。

如您所见,在打印结果时会发生错误。 在回溯中可以看到,函数PRIN1用于打印节点结构。 您的函数已经返回了结果,现在需要在REPL中打印该结果。

您的函数返回一个循环数据结构,Lisp尝试打印它。 然后进入无限循环。

您需要告诉Lisp,它应该处理打印机中的循环数据结构。

采用

(setf *print-circle* t)

然后再试一次。

一点风格指南:

  • 通常使用CLOS类代替结构
  • 为每种结构提供定制打印机,尤其是具有圆形的结构
  • 从函数返回有意义的结果

  ask by turingcomplete translate from so

未解决问题?本站智能推荐: