Обход дерева LISP

Я пытаюсь вернуть список узлов дерева (не обязательно двоичного дерева), к которому обращались.

Дерево представляется в виде списка с подсписками, например: (a (b) (c (d) (e))), b - левое поддерево, (c (d) (e)) - правое поддерево, a -root. Результат должен быть: 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 ответ

Бесконечная рекурсия вызвана тем фактом, что число никогда не бывает ложным.
замещать (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 - cadr), а правое поддерево - это третий элемент (car из cdr из cdr - caddr), а не остальная часть списка, начиная с третьего пункта, как вы написали.
Вам необходимо извлечь поддерево:

(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)
Другие вопросы по тегам