Tree 在公共LISP中使用前序和顺序重建树

Tree 在公共LISP中使用前序和顺序重建树,tree,lisp,common-lisp,binary-tree,allegro-cl,Tree,Lisp,Common Lisp,Binary Tree,Allegro Cl,由于我一直在学习LISP和阅读实用的通用LISP,我发现了一些问题并试图解决它们,我在这个特定的问题上陷入了困境,不确定如何解决,因此希望得到一些帮助/建议 我需要能够从它的前序和索引中创建一个后序树 例如,如果给出以下内容: 预订单:A B D E C F 顺序:D B E A C F 输出将是后序:debbfca 从我所看到的,inoder的第一个元素始终是postorder的第一个元素,因此我开始编写代码来反映这一点: (defun tree-recovery (preorder inor

由于我一直在学习LISP和阅读实用的通用LISP,我发现了一些问题并试图解决它们,我在这个特定的问题上陷入了困境,不确定如何解决,因此希望得到一些帮助/建议

我需要能够从它的前序和索引中创建一个后序树

例如,如果给出以下内容:

预订单:A B D E C F

顺序:D B E A C F

输出将是后序:debbfca

从我所看到的,inoder的第一个元素始终是postorder的第一个元素,因此我开始编写代码来反映这一点:

(defun tree-recovery (preorder inorder)
  (let (root)
    (setf root (first inorder))))

但我不知道从这里到哪里去,任何帮助都将不胜感激!谢谢

如果我们将函数命名为树恢复,让它恢复树 而不是构建后序序列。(比我聪明的人 需要解决问题,而无需实际重建 树)

Inorder和postorder从同一个元素开始,但该元素是 非根:前序序列的第一个元素是根

假设所有序列元素都是 可通过
EQL
进行比较的非零原子。我们将把一片叶子表示为一片叶子 atom的值,其他节点为
(左-右列表根)
,以及空 子树为NIL

(defun tree-recovery (preorder inorder)
  (if (rest preorder)
      (let* ((root (pop preorder))
             (inorder-root-tail
               (member root inorder))
             (inorder-left
               (ldiff inorder inorder-root-tail))
             (left-length
               (length inorder-left))
             (inorder-right
               (rest inorder-root-tail))
             (preorder-left
               (subseq preorder 0 left-length))
             (preorder-right
               (subseq preorder left-length)))
        (list root
              (tree-recovery preorder-left inorder-left)
              (tree-recovery preorder-right inorder-right)))
      (first preorder)))
空树归零。对于单叶节点的平凡树,我们 返回一个值

对于其他树,我们首先从
preorder
中弹出根元素(其中 这是第一次)。然后我们找到一个子列表,它以中的根元素开始
顺序
。我们使用它来获得与我们的 左子树和一段与我们的右 子树。知道左子树的大小,我们得到左和右 一块
预订单
很容易

现在,当我们有一棵树时,进行后序遍历很容易:

(defun postorder (tree)
  (and tree ;; non-empty
       (if (consp tree) ;; non-leaf
           (destructuring-bind (root left right) tree
             (append (postorder left)
                     (postorder right)
                     (postorder root)))
           (list tree))))
让我们试试:

(postorder 
 (tree-recovery '(a b d e c f)
                '(d b e a c f)))
=> (D E B F C A)

似乎有效。

看看如果树包含具有相同内容的节点,树的前序为“(cons-cons-f-nil-cons-1-cons-2-cons-3-nil-nil-nil-nil)”,它是否有效?实际上,它甚至可能在任何嵌套的cons树上中断,如
(cons(cons-x-nil)nil)