Tree LISP中的树遍历

Tree LISP中的树遍历,tree,lisp,common-lisp,inorder,Tree,Lisp,Common Lisp,Inorder,我试图返回树的节点列表,但不一定是按顺序访问的二叉树 树表示为带有子列表的列表,例如:a b c d e、b-左子树、c d e-右子树、a-根。 结果应该是:b,a,d,c,e 这是我的代码,但我似乎总是得到堆栈溢出错误。有人能帮我吗 ;return left-subtree (defun left-tree(tree) (cond ((null tree) NIL) ((not (listp tree)) NIL) (t (car (cdr tree))) ) )

我试图返回树的节点列表,但不一定是按顺序访问的二叉树

树表示为带有子列表的列表,例如:a b c d e、b-左子树、c d e-右子树、a-根。 结果应该是: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))
  )
 )
)

无限递归是由一个数字从来都不是假y这一事实引起的。 将非列表长度树替换为空树。 也就是说,在结构上递归,而不是在大小上递归

一旦你修复了这个问题,你会得到一个类型错误,因为你的基本案例结果是inorder-它应该是nil,而不是0

一旦解决了该问题,您将发现另一个问题:

CL-USER> (inorder '(a (b) (c (d) (e))))
(B A (C (D) (E)))
这是不正确的

如果你看右树的结果,它实际上并不是你所声称的那样:

CL-USER> (right-tree '(a (b) (c (d) (e))))
((C (D) (E)))
如您所见,这是一个单元素列表,其中包含正确的子树,而不是正确的子树。 单独测试每个函数是一个好主意,尤其是如果您确信它们是正确的

根是第一个列表项car,左子树是第二个列表项cdr-cadr的car,右子树是第三个列表项cdr-caddr的cdr的car,而不是列表中从第三个项目开始的其余部分。 您需要提取子树:

(defun right-tree(tree)
  (cond
    ((null tree) NIL)
    ((not (listp tree)) NIL)
    (t (caddr tree))))

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

不列出长度树的目的是什么?不是一个数字的顺序总是错误的。树遍历的顺序通常是预先排序的根、左、右;后序左、右、根;按左、根、右的顺序排列。我知道您发布了一个输出示例,但当您有两个以上的孩子时,顺序意味着什么?例如,如果你有一棵树,那么顺序遍历应该是什么?另一个问题是,当您希望最终得到一个平面列表时,您在对inoder的每次求值中都会创建一个新列表。中有关car/cdr递归的部分可能会对您有所帮助。请正确设置代码的格式、缩进和排列位置。事实并非如此,它几乎不可读。