📅  最后修改于: 2020-11-03 07:17:38             🧑  作者: Mango
您可以从cons单元构建树数据结构,作为列表列表。
要实现树结构,您将必须设计将以特定顺序遍历cons单元的功能,例如,二叉树的前顺序,后顺序和后顺序。
让我们考虑由cons单元组成的树结构,这些结构形成以下列表列表-
((1 2)(3 4)(5 6))。
用图解法,它可以表示为-
尽管大多数情况下,您将需要根据特定需要编写自己的树功能,但是LISP提供了一些可以使用的树功能。
除了所有列表功能,以下功能特别适用于树结构-
Sr.No. | Function & Description |
---|---|
1 |
copy-tree x & optional vecp It returns a copy of the tree of cons cells x. It recursively copies both the car and the cdr directions. If x is not a cons cell, the function simply returns x unchanged. If the optional vecp argument is true, this function copies vectors (recursively) as well as cons cells. |
2 |
tree-equal x y & key :test :test-not :key It compares two trees of cons cells. If x and y are both cons cells, their cars and cdrs are compared recursively. If neither x nor y is a cons cell, they are compared by eql, or according to the specified test. The :key function, if specified, is applied to the elements of both trees. |
3 |
subst new old tree & key :test :test-not :key It substitutes occurrences of given old item with new item, in tree, which is a tree of cons cells. |
4 |
nsubst new old tree & key :test :test-not :key It works same as subst, but it destroys the original tree. |
5 |
sublis alist tree & key :test :test-not :key It works like subst, except that it takes an association list alist of old-new pairs. Each element of the tree (after applying the :key function, if any), is compared with the cars of alist; if it matches, it is replaced by the corresponding cdr. |
6 |
nsublis alist tree & key :test :test-not :key It works same as sublis, but a destructive version. |
创建一个名为main.lisp的新源代码文件,然后在其中键入以下代码。
(setq lst (list '(1 2) '(3 4) '(5 6)))
(setq mylst (copy-list lst))
(setq tr (copy-tree lst))
(write lst)
(terpri)
(write mylst)
(terpri)
(write tr)
当您执行代码时,它返回以下结果-
((1 2) (3 4) (5 6))
((1 2) (3 4) (5 6))
((1 2) (3 4) (5 6))
创建一个名为main.lisp的新源代码文件,然后在其中键入以下代码。
(setq tr '((1 2 (3 4 5) ((7 8) (7 8 9)))))
(write tr)
(setq trs (subst 7 1 tr))
(terpri)
(write trs)
当您执行代码时,它返回以下结果-
((1 2 (3 4 5) ((7 8) (7 8 9))))
((7 2 (3 4 5) ((7 8) (7 8 9))))
让我们尝试使用LISP中可用的列表功能来构建自己的树。
(defun make-tree (item)
"it creates a new node with item."
(cons (cons item nil) nil)
)
接下来,让我们在树中添加一个子节点-它需要两个树节点,并将第二个树添加为第一棵树的子节点。
(defun add-child (tree child)
(setf (car tree) (append (car tree) child))
tree)
此函数将给第一个子节点返回一个给定的树-它将获取一个树节点并返回该节点的第一个子节点;如果该节点没有任何子节点,则返回nil。
(defun first-child (tree)
(if (null tree)
nil
(cdr (car tree))
)
)
此函数将返回给定节点的下一个同级节点-它以树节点作为参数,并返回对下一个同级节点的引用;如果该节点不包含任何节点,则返回nil。
(defun next-sibling (tree)
(cdr tree)
)
最后,我们需要一个函数来返回节点中的信息-
(defun data (tree)
(car (car tree))
)
此示例使用上述功能-
创建一个名为main.lisp的新源代码文件,然后在其中键入以下代码。
(defun make-tree (item)
"it creates a new node with item."
(cons (cons item nil) nil)
)
(defun first-child (tree)
(if (null tree)
nil
(cdr (car tree))
)
)
(defun next-sibling (tree)
(cdr tree)
)
(defun data (tree)
(car (car tree))
)
(defun add-child (tree child)
(setf (car tree) (append (car tree) child))
tree
)
(setq tr '((1 2 (3 4 5) ((7 8) (7 8 9)))))
(setq mytree (make-tree 10))
(write (data mytree))
(terpri)
(write (first-child tr))
(terpri)
(setq newtree (add-child tr mytree))
(terpri)
(write newtree)
当您执行代码时,它返回以下结果-
10
(2 (3 4 5) ((7 8) (7 8 9)))
((1 2 (3 4 5) ((7 8) (7 8 9)) (10)))