Lisp 获取列表中elt的cdr

Lisp 获取列表中elt的cdr,lisp,common-lisp,Lisp,Common Lisp,我使用了两种方法来构建基于cons单元的树 (defun make-tree (nodes) (cons nodes NIL)) (defun add-child (tree child) (setf (cdr tree) (append (cdr tree) child))) 然后我创建了4个参数: (defparameter *root* (make-tree "root")) (defparameter *a* (make-tree "a")) (defparameter *b

我使用了两种方法来构建基于cons单元的树

(defun make-tree (nodes)
  (cons nodes NIL))

(defun add-child (tree child)
  (setf (cdr tree) (append (cdr tree) child)))
然后我创建了4个参数:

(defparameter *root* (make-tree "root"))
(defparameter *a* (make-tree "a"))
(defparameter *b* (make-tree "b"))
(defparameter *c* (make-tree "c"))
我构建了以下树:

(add-child *root* *a*)
(add-child *root* *b*)
(add-child *a* *c*)
控制台中将显示
*根*

CL-USER> *root*
("root" "a" "b")

我的问题是:是否可以从
*root*
检索
c
?类似于:
(cdr(car(cdr*root*))
返回一个错误。

您需要使用
ncoc
,而不是
中的
APPEND
,这样您就不会复制子树

(defun add-child (tree child)
  (setf (cdr tree) (append (cdr tree) child)))
通过此更改,在完成所有其他步骤后,我得到:

> *root*
("root" "a" "b" "c")
> (car (cdr (cdr (cdr *root*))))
"c"
> (cadddr *root*)
"c"

c
不在从
*根*
开始的树中
添加子项
在使用
追加
时会创建一个副本,因此
(添加子项*a**c*)
会将子项添加到
*a*
,但不会添加到
*根*
下的副本。请尝试使用
NCOC
而不是
追加
,这样您就不会创建副本了。谢谢,这有助于我指出一些现有的疑问:您想要的实际上是相反的,因为您想要共享结构。@Xaving,还要注意还有and.Ok。它回答了我的问题。但是通过这一点,我失去了树结构(因为b变成了a的孩子)。为了管理一棵树,我现在将讨论这种方法。问题是,您的结构实际上不是一棵树。这只是一个链表,因为你只添加到CDR,而不是汽车。