gpt4 book ai didi

在 COMMON LISP 中使用预序和中序重建树

转载 作者:太空宇宙 更新时间:2023-11-03 18:48:16 24 4
gpt4 key购买 nike

由于我一直在学习 LISP 和阅读实用的通用 lisp 我发现了问题并试图解决它们我一直被这个特定问题所困扰并且不确定如何解决它所以需要一些帮助/建议。

我需要能够根据其前序和中序创建后序树

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

预购:A B D E C F

顺序:D B E A C F

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

据我所知,中序的第一个元素始终是后序的第一个元素,因此我开始编写代码来反射(reflect)这一点:

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

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

最佳答案

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

中序和后序以相同的元素开始,但那个元素是不是根:前序序列的第一个元素是根。

让我们恢复树,假设所有序列元素都是可通过 EQL 比较的非零原子。我们将叶子表示为原子的值,其他节点为 (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 对应我们的右子树子树。知道我们的左子树的大小,我们得到左子树和右子树一段 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)

似乎有效。

关于在 COMMON LISP 中使用预序和中序重建树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14781837/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com