【问题标题】:Searching Binary Trees in Lisp在 Lisp 中搜索二叉树
【发布时间】:2014-11-16 12:22:59
【问题描述】:

我被要求创建一个函数,其中用户指定一个目标和一棵二叉树,然后该函数将返回到达该节点所需的路径。

即用户将提供此 (searchtree 'b '(((a . b). c).(d .((e . f). g)))) 并且控制台将左左右打印。

我有几个问题。

我的理解是,在 Lisp 中使用树时,我必须使用 defun 叶、节点、然后检索节点和元素的方法以及在开始之前识别它是叶还是节点的方法来构造树构造进一步的函数来搜索树。但问题的措辞表明我的解决方案过于复杂了。

有人可以将我推向正确的方向,让我知道我应该做什么,或者建议一个资源来更好地理解这个问题。

提前致谢。

【问题讨论】:

  • 先写“return”,然后写“print”。应该是哪个?

标签: tree common-lisp


【解决方案1】:

您在示例中用于表示树的数据结构是使用cons 构造的列表:

? '(((a . b). c) . (d . ((e . f) . g)))
(((A . B) . C) D (E . F) . G)

相同
? (cons (cons (cons 'a 'b) 'c) (cons 'd (cons (cons 'e 'f) 'g)))
(((A . B) . C) D (E . F) . G)

但是,您可以使用不同的表示形式,例如使用defstruct 构造的结构。因此,创建抽象函数来构造树、提取左右、测试节点和叶子是有意义的。

对于列表,您可以使用:

(defun mktree (left right) (cons left right))
(defun nodep (tree) (consp tree))
(defun leafp (tree) (atom tree))
(defun left  (tree) (car tree))
(defun right (tree) (cdr tree))

? (mktree (mktree (mktree 'a 'b) 'c) (mktree 'd (mktree (mktree 'e 'f) 'g)))
(((A . B) . C) D (E . F) . G)

而对于结构,定义如下:

(defstruct (btree) left right)
(defun mktree (left right) (make-btree :left left :right right))
(defun nodep (tree) (btree-p tree))
(defun leafp (tree) (not (nodep tree)))
(defun left  (tree) (btree-left tree))
(defun right (tree) (btree-right tree))

? (mktree (mktree (mktree 'a 'b) 'c) (mktree 'd (mktree (mktree 'e 'f) 'g)))
#S(BTREE :LEFT #S(BTREE :LEFT #S(BTREE :LEFT A :RIGHT B) :RIGHT C) :RIGHT #S(BTREE :LEFT D :RIGHT #S(BTREE :LEFT #S(BTREE :LEFT E :RIGHT F) :RIGHT G)))

无论哪种方式,您的 searchtree 函数都可以以独立于您的表示的方式编写:

(defun searchtree (atm tree)
  (labels
      ((sub (tree res)
         (cond
          ((nodep tree) 
           (sub (left  tree) (cons 'left  res))
           (sub (right tree) (cons 'right res)))
          ((leafp tree)
           (when (eql atm tree)
             (return-from searchtree (reverse res)))))))
    (sub tree nil)))

所以不管你得到什么样的代表

? (searchtree 'b (mktree (mktree (mktree 'a 'b) 'c) (mktree 'd (mktree (mktree 'e 'f) 'g))))
(LEFT LEFT RIGHT)

【讨论】:

  • 谢谢你的帮助,你能通过搜索树功能告诉我吗?
猜你喜欢
  • 1970-01-01
  • 2019-04-09
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 2012-12-27
  • 1970-01-01
  • 2022-01-24
相关资源
最近更新 更多