【问题标题】:Tree reconstruction using preorder and inorder in COMMON LISP在 COMMON LISP 中使用前序和中序重建树
【发布时间】:2013-01-24 18:22:57
【问题描述】:

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

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

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

预购:A B D E C F

顺序:D B E A C F

输出将是后序:D E B F C A

据我所知,中序的第一个元素始终是后序的第一个元素,所以我开始编写代码来反映这一点:

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

但我不确定从这里去哪里,任何帮助将不胜感激!谢谢

【问题讨论】:

标签: tree lisp common-lisp binary-tree allegro-cl


【解决方案1】:

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

Inorder 和 postorder 以相同的元素开始,但该元素是 not root:preorder序列的第一个元素是root。

让我们恢复树,假设所有序列元素都是 非零原子可与EQL 进行比较。我们将叶子表示为 atom的值,其他节点为(list root left right),以及一个空的 子树为 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)))

对于空树,我们返回 NIL。对于一个叶子节点的平凡树,我们 返回一个值。

对于其他树,我们首先从preorder弹出根元素(其中 这是第一个)。然后我们找到一个以根元素开头的子列表 inorder。我们使用它来获取对应于我们的inorder 左子树和一块inorder对应我们的右边 子树。知道了我们左子树的size,我们得到了left和right 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)
猜你喜欢
  • 2010-10-27
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-26
相关资源
最近更新 更多