Lisp中树结构的定义

时间:2014-07-31 06:44:12

标签: tree lisp common-lisp

来自Common Lisp HyperSpec词汇表:

  

tree n。 1.由conses和。组成的二进制递归数据结构   原子:conses本身也是树(有时称为   "子树"或者"分支"),原子是终端节点(有时候   叫叶子)。通常,叶子代表数据而   分支机构建立了一些关系。一般来说,   任何具有"分支"概念的递归数据结构和   树叶。

     

tree structure n。 (树的)构成树的一组果。   请注意,虽然每个这样的缺点的汽车[1b]组件是其中的一部分   树形结构,树中每个缺点的汽车的对象   它们本身不是树结构的一部分,除非它们也是   conses之外。

树形结构定义中的最后一句提出了一个问题,即对cdrs也可以这么说吗?

在" tree"的定义中使用二进制一词似乎表明,对于树木而言,汽车与cdr之间没有区别,但是树木结构的定义"似乎对待汽车特别,所以我很困惑。

2 个答案:

答案 0 :(得分:3)

简短回答

  

树结构定义中的最后一句提出了一个   问题,也就是说,关于cdrs也可以这么说吗?

我认为答案是肯定的。对于列表结构有类似的定义,几乎相同的措辞。关于利弊汽车的价值是否是列表结构的一部分的列表结构中存在更多混淆的可能性,因为问题可能出现,例如,“在列表中替换X是什么意思(X(X) Y)?”由于cdr是列表的 rest ,因此cdr并没有太多问题。它显然是列表结构的一部分。

对于树结构,我认为模糊性较小;汽车或cdr的缺点是一个子树。 树结构列表结构的定义几乎相同,如果有人为列表结构编写了定义,我不会感到惊讶,然后将其复制到树结构,使必要的最小数量的更改准确。这样可以在那里留下关于汽车的信息,即使它回答的问题可能不会在实践中出现。

更长的答案

让我们看看列表结构的定义并比较:

  

list structure n。 (列表中)组成列表的一组conses。   请注意,虽然每个这样的利弊的汽车组成部分是   列表结构,作为列表元素的对象(即,   作为列表中每个缺点的汽车的对象)不是   它们本身就是它的列表结构的一部分,即使它们是一致的,除了   在(循环)情况下,列表实际上包含其中一个   尾巴作为一个元素。 (有时列表的列表结构   按顺序冗余地称为“顶级列表结构”   强调任何作为列表元素的conses都不是   参与。)

请注意这些区别的具体位置:

  

(列表结构)请注意,虽然每个这样的利弊的汽车组成部分是   列表结构,作为列表元素的对象(即,   作为列表中每个缺点的汽车的对象)不是   它们本身就是列表结构的一部分,即使它们是一致的。

  

(树形结构)请注意,虽然每个这样的利弊的汽车组成部分   树形结构,树中每个缺点的汽车的对象   它们本身不是树结构的一部分,除非它们也是   conses之外。

这意味着在

(1 (2) 3) == (cons 1 (cons (cons 2 nil) (cons 3 nil)))

列表结构中有三个缺点单元格,树结构中有四个缺点单元格。

这究竟在哪里?精确定义这些术语变得很重要,这样规范就可以轻松定义特定函数遍历或修改列表或树的哪些部分。

nsubst可以修改树结构

例如,函数nsubst and friends,其文档说明:

  

nsubst,nsubst-if和nsubst-if-not可能会改变tree structure   树。

树形结构的特定定义使我们能够理解 nsubst 可能会和不会改变哪些内容。

  

tree structure n。 (树的)构成树的一组果。   请注意,虽然每个这样的利弊的汽车组成部分是   树形结构,树中每个缺点的汽车的对象   它们本身不是树结构的一部分,除非它们也是   conses之外。

所以,这告诉我们的是,对于树中的任何cons单元 x nsubst 可能会(setf(car x)...)< / strong>,以便(car x)以后可能会有所不同,但它不会修改(car x)返回的实际对象(当然,除非它是一个缺点)。在(car x)的值是可能在其中具有树的对象的情况下,这可能很重要。因此,例如, nsubst 不会下降到向量中,但它将替换向量:

(let* ((l (list 1 2 3))     ; a list
       (v (vector 0 l 4))   ; a vector that contains the list (and other elements)
       (tree (cons l v)))   ; a tree containing the list and the vector
  (nsubst 'x l tree))       ; replace the list in the tree with X
;=> (X . #(0 (1 2 3) 4))    ; nsubst doesn't descend into the vector, because it's
                            ; not tree structure

delete-duplicates可以修改列表结构

另一方面,delete-duplicates只会修改列表结构:

  

delete-duplicates,当sequence是一个列表时,允许setf any   part,car或cdr,该序列中的顶级列表结构。   当序列是向量时,允许删除重复项进行更改   矢量的尺寸并将其元素滑动为新的   位置没有置换它们以产生最终的矢量。

答案 1 :(得分:2)

  

请注意,虽然每个这样的利弊的汽车[1b]组成部分是   树形结构,树中每个缺点的汽车的对象   它们本身不是树结构的一部分,除非它们也是   conses之外。

据我所知,这个定义的作者试图画出树本身与其对象之间的界限。所以它说只有conses才能组成树的结构。

考虑这个例子:

(1 2 (3 "string") 4)

虽然对象"string"是树的一部分(它是car的{​​{1}}),但它不是树结构的一部分,因为字符串不是由缺点组成的细胞

我认为该定义的作者考虑了正确的列表,因为对于他们来说,每个元素都是("string")

car

(cons "foo" (cons "bar" (cons "baz" nil))) ; ^car^ ^car^ ^car^ 在适当列表的情况下定义树的结构。

但您也可以将以下内容视为树:

cdr

在这种情况下,("foo" . "bar") 不会成为树结构的一部分。