从根到给定节点的路径n-ary树lisp没有map / lambda / labels

时间:2016-01-07 07:12:43

标签: tree lisp common-lisp

我知道之前已经问过这个问题,但只有map / lambda / labels才能解决,我希望它尽可能基本解决

我想将路径从根返回到树的给定节点,如下所示:

  A
 / \
B   C
   / \
  D   E

给出为:(A 2 B 0 C 2 D 0 E 0) 从A(根)到给定节点E的路径是:A C E

在找到元素的确切位置之前,我不知道如何保留路径。 我应该保存部分结果吗?有什么帮助吗?

我试过检查元素是否在......但是我无法构造路径

(defun isinh (l a p)
  (cond ((null l) p)
        ((equal (car l) a) (isinh (cdr l) a 1))
        (t (isinh (cdr l) a p))))

(defun isin (l a)
  (cond (t (isinh l a 0))))

(defun p15 (l el)
  (cond ((null l) '())
        ((equal (car l) el) (list el))
        ((and (listp (car l))
              (= (isin (car l) el)))
         (p15 (car l) el))
        ((and (listp (cadr l))
              (= (isin (cadr l) el)))
         (p15 (cadr l) el))
        ((not (equal (car l) el))
         (cons (car l) (p15 (cdr l) el)))))

1 个答案:

答案 0 :(得分:1)

一种可能的解决方案是在列表结构中转换树,其中第一个元素是根,第二个元素是左子元素,第三个元素是右子元素,然后使用简单的递归函数搜索路径

要转换列表结构中的树,请参阅此问题的答案:transforming trees in lisp

查找路径的递归函数如下:

(defun path(tree el)
  (cond ((null tree) nil)
        ((eql (first tree) el) (list el))
        (t (let ((lpath (path (second tree) el)))
             (if lpath
               (cons (first tree) lpath)
               (let ((rpath (path (third tree) el)))
                 (when rpath
                   (cons (first tree) rpath))))))))

<强>更新

以前的版本仅适用于二叉树,n-ary树的版本如下:

(defun path(tree el)
  (cond ((null tree) nil)
        ((eql (car tree) el) (list el))
        (t (loop for child in (rest tree)
              for child-path = (path child el)
              when child-path
              do (return-from path (cons (car tree) child-path))))))

(path '(a (b (c)) (d (e) (f)) (g (h) (i (j)))) 'j)  ;  =>  (A G I J)