Prolog二叉树搜索

时间:2018-06-03 09:49:54

标签: tree prolog max binary-tree breadth-first-search

我遇到过这个问题:

  

写一个PROLOG程序,给出一个存储在节点中的整数的二叉树。写一个   返回存储在树中的最大值的程序。例如,给定输入[4,[1,[],[]],[7,[],[]]],算法应返回7

我想我必须使用BFS。这是我关于BFS的讲义:

  

bf(X,Y), Y是包含树X元素的列表,在广度优先访问中遇到。

bf([], []).
bf([void | Rest], Y):- bf(Rest, Y).
bf([tree(Integer, Right, Left) | Rest], [Integer | Y]) :- 
    append(Rest, [Left, Right], Nodes), 
    bf(Nodes, Y).

我甚至不知道所有变量的意思......会喜欢一些帮助。

1 个答案:

答案 0 :(得分:0)

好的,你展示的bf/2谓词很好,除了说明应该是

  

bf( [X], Y)Y是包含树X元素的列表,在树遍历的广度优先顺序中遇到。

这里再次提供一些较长的描述性变量名称(我通常喜欢非常简短,甚至是单字母的名称,如果需要,可以在评论中加上描述;你可能也会这样做,以后,当你'对Prolog更加满意),并将一些暗示的统一性变成了明确的统一:

bf(Queue, Integers) :- 
    Queue    = [],                     %% breadth-first enumeration of the empty queue
    Integers = [].                     %% is the empty list

bf([HeadOfQueue | RestOfQueue], Integers):- 
    HeadOfQueue = void,                %% empty tree in the queue,
    bf(RestOfQueue, Integers).         %% go on with the same Integers list to fill

bf([HeadOfQueue | RestOfQueue], Integers) :- 
    HeadOfQueue = tree(Integer, Right, Left),            %% a tree in the queue,
    Integers = [Integer | MoreIntegers],                 %% fill the list's head
    append(RestOfQueue, [Left, Right], ExtendedQueue),   %% extend the popped queue
                                                         %%   with Left, then Right,
    bf(ExtendedQueue, MoreIntegers).                     %% and keep going

它会弹出一个节点"议程"取出节点的整数,将其放入以自上而下方式构建的结果列表中,将节点的两个子节点附加到议程后面,并进行递归。因此,应该使用[Tree]作为初始队列来调用它。因此,树以FIFO顺序考虑,实现了树的广度优先枚举。 LIFO会让我们获得深度优先。

唯一剩下的就是 什么样的树适合工作?答案就在代码中:它是表格的复合词

    tree( Int, RightChild, LeftChild )

显然RightChildLeftChild应该是相同形式的树木/复合词, ... 你看到了吗? ......原子void。最有可能表示空树。

您在示例中显示的树有另一个结构,大概是[Int, LeftChild, RightChild]的结构。您只需调整bf/2谓词即可适应新的预期数据格式。

我们可以通过首先概括定义抽象对数据细节进行

来做到这一点
bf([], []).                       %% implicit unifications, shorter names
bf([Empty | Rest], Y):- 
    empty(Empty),                                  %% data abstraction!
    bf(Rest, Y).
bf([Node | RestOfQueue], [Integer | Y]) :- 
    node(Node, Integer, Left, Right),              %% data abstraction!
    append(RestOfQueue, [Left, Right], ExtendedQueue), 
    bf(ExtendedQueue, Y).

empty( void ).
node( tree(Integer, Right, Left), Integer, Left, Right ).

现在要做的就是重新定义empty/1node/4以匹配您的种树编码。这应该很简单。它就在您的示例数据中:

              [4,
                 [1, [], []],
                 [7, [], []]  ]

所以,

empty( ... ).
node( [ ..., ...., ... ] , ..., ..., ... ).

完成后,我们定义

maximum_element(Tree, MaxElem ):-
    bf( [Tree],  TreeElements ),
    list_maximum( TreeElements, MaxElem ).
首先

,但是我们可以将两个子目标融合为一个,这样最大整数的选择都是在树遍历过程中完成的,而不是构建整个列表他们先。