maplist如何在将元素插入AVL树的程序中工作

时间:2013-04-30 18:06:05

标签: prolog

我正在学习Prolog,但我无法学习,所以我对SWI Prolog谓词中构建的地图列表的特定用法存有疑问。

让我解释一下我的情况:

我有一个名为 addavl(Tree/Height, Element, NewTree/Height) 的个人谓词,将元素 Element 插入到AVL树 Tree < / strong>(其中 Height 是此原始树的高度)并生成名为 NewTree 的新AVL树,其中包含 { {1}} 并且有一个新的高度 Element

现在我有一个元素列表,我会将这些元素添加到AVL树(开头是无效的),所以我有以下谓词(工作正常)。

我对谓词中使用的 Height SWI Prolog有一些疑问,我也知道我对所有这些谓词的一般解释是否正确或者我是否遗漏了某些内容

maplist/4

我对整个谓词的解释如下:

首先 /* Predicate that from a given list of elements build an AVL Tree: */ buildTree(List,Tree):- length(List, N), % N: the number of element in List /* Create L1 as a list that have the same number of element of List For example if List have N=4 element L1=[A,B,C,D] where A,B,C,D are variable that are not yet set */ length(L1,N), /* Se fosse: append(L1,[Tree],NewList) otterrei: NewList=[A,B,C,D|Tree] ma essendo NewList=[_|L2] so L2=[B,C,D|Tree] */ append(L1,[Tree],[_|L2]), /* Put the couple (nil,0) in the L1 head so I have that A=(nil,0) that represents an empty AVL tree: */ L1=[nil/0 |_], /* Call addavl passing as parameter the tree in the L1 head, the value to insert in the List Head and the head of L2 as the current new Tree- When the variable Tree is reached it represents the final AVL tree */ maplist(addavl, L1, List, L2). 变量包含我要在AVL树中插入的原始元素列表 N 的长度

然后创建一个新列表 List ,其中包含原始列表的相同数量的元素 L1 ,但在这种情况下List包含尚未设置值的变量。

例如,如果原始元素列表是: L1 List = [5, 8, 3, 4]列表将类似于: L1 其中L1 = [A, B, C, D]是尚未定价的变量。

现在必须满足这个陈述:

A, B, C, D
我以这种方式阅读:

如果我有 append(L1,[Tree],[_|L2]), 而不是之前的陈述,那么我会:

append(L1,[Tree],NewList) 其中NewList = [A,B,C,D,Tree]A,B,C,D列表的先前未设置变量, L1 是新的未设置变量。

但就我而言,我有 Tree 所以 NewList = [_|L2]

现在,前一个L2 = [B,C,D,Tree]操作的含义是append列表的创建,该列表在开头包含L2而不是有价值的变量(在前面的例子中4不是有价值的变量:{ {1}}, n )。

这些变量中的每一个都代表一个树,其中在原始列表中插入了一个新元素B,C,D

所以,在开始时,程序通过以下指令将void AVL树放在此列表的头部(在我的Tree变量的示例中):List

所以在A变量的头部,有一个空洞树,其高度为0(而空树是正确的AVL树)

现在我有了 FIRST DOUBT :通过上一个操作我已经对L1=[nil/0 |_]列表的head变量进行了定值,但是在此操作的前一步我创建了 {{ 1}} 使用此语句列出:

L1

这意味着 L1 列表的NewList=[_|L2]匿名变量与 append(L1,[Tree],[_|L2]) AVL树匹配? 这项工作也是这样的,如果我在之后_,我已经创建了[_|L2]列表nil/0列表L1

好的,如果我的解释是正确的,请继续我的 SECOND DOUBT ,这与在谓词中构建的地图列表 SWI Prolog的确切工作方式有关。

我有:

[_|L2]

这个谓词究竟是什么?

阅读官方文件:http://www.swi-prolog.org/pldoc/man?predicate=maplist%2F2

在我看来,以下列方式工作:

我的 L1 谓词是 GOAL,必须在列表的每个元素上得到满足

记住[Tree]谓词以这种方式工作: maplist(addavl, L1, List, L2).

所以:

1) addavl 是AVL树的列表(第一个是无效的AVL树: addval

2) addavl(Tree/Height, Element, NewTree/Height) 是包含要插入的元素的原始列表

3) L1 是包含我将创建的AVL树的列表。

所以我认为现在按以下方式工作:

首先从nil/0的头部获取void AVL Tree( List ),从List中添加第一个元素,执行GOAL(将此元素插入到void AVL Tree)并将结果放在L2列表的头部(根据我之前的示例,它是nil/0变量,因此L1变量包含AVL树其中包含 L2 元素的第一个元素)列表**

然后重复此过程,插入元素列表 B 中的所有其他元素,最后,B列表的最后一个元素( {{ 1}} 变量)将代表插入所有元素的最终AVL树。

我的推理是正确的还是我错过了什么?

1 个答案:

答案 0 :(得分:2)

在Prolog中我们说“尚未实例化的变量”或“未实例变量”。

关于L1=[nil/0 |_],我们可以将其称为“使用初始值初始化它”。

_中的[_|L2]确实与init值匹配,我们并不关心它。

(这给出了调用append(L1, [Tree], [nil/0 | L2])的想法,而不是原始代码中的两次调用。)

是的,操作顺序并不重要。 X=t(A), A=2A=2, X=t(A)都会导致相同的替换A=2, X=t(2)

maplist( pred, ...Lists ...)的作用是pred必须满足列表中的元素,成对(或按列)。例如。 maplist(plus, [1,2,3],[4,X,8],[5,6,Y])

列表L1L2 共享结构

nil/0   B   C   D   Tree
------------------
       L1
        -----------------
               L2

maplist通过将按列提供给addavl来查看它们并对其进行处理:

nil/0   B     C     D       % L1
 E1     E2    E3    E4      % List
 B      C     D    Tree     % L2

所以是的,就像你说的那样。


我认为你的老师不会接受这个答案。您应该编写直接递归解决方案。两种变体都描述了相同的迭代计算过程,逐步将元素添加到树中,使用先前调用的输出作为下一个调用的输入。但是在任何给定的实现中,可以比另一个更好地优化。在这里,使用列表的效率很可能低于递归变量。