树遍历为了LISP

时间:2015-12-08 22:15:39

标签: tree lisp common-lisp inorder

我正在尝试返回按顺序访问的树的节点列表(不一定是二叉树)。

树被表示为带有子列表的列表,例如:(a(b)(c(d)(e))),b - 左子树,(c(d)(e)) - 右 - 子树,一个根。 结果应该是:b,a,d,c,e

这是我的代码,但我似乎总是得到"堆栈溢出"错误。有人可以帮帮我吗?

;return left-subtree
(defun left-tree(tree)
  (cond
   ((null tree) NIL)
   ((not (listp tree)) NIL)
   (t (car (cdr tree)))
  )
)

;return right-tree
(defun right-tree(tree)
  (cond
   ((null tree) NIL)
   ((not (listp tree)) NIL)
   (t (cdr (cdr tree)))
  )
)

;perform inorder
(defun inorder(tree)
  (if (not (list-length tree)) 0
  (append
   (inorder (left-tree tree))
   (list (car tree))
   (inorder (right-tree tree))
  )
 )
)

1 个答案:

答案 0 :(得分:2)

无限递归是由数字永远不是假y引起的 将(not (list-length tree))替换为(null tree) (也就是说,对结构进行递归,而不是超过尺寸。)

解决此问题后,由于inorder中的基本案例结果,您会收到类型错误 - 它应该是nil,而不是0

修复 后,您会发现另一个问题:

CL-USER> (inorder '(a (b) (c (d) (e))))
(B A (C (D) (E)))

这远非正确。

如果您查看right-tree的结果,实际上并不是您声称的结果:

CL-USER> (right-tree '(a (b) (c (d) (e))))
((C (D) (E)))

如您所见,这是一个单元素列表,其中包含正确的子树,而不是正确的子树。
(单独测试每个函数是个好主意,特别是如果你确定它们是正确的。)

根是第一个列表项(car),左子树是第二个(car - cdr的{​​{1}}),右边是子树是第三个cadr - car的{​​{1}}的{​​{1}},而不是列表的其余部分你写的第三个项目 您需要提取子树:

cdr