PROLOG(如何对多路树进行后序排序)

时间:2013-11-17 20:20:23

标签: prolog dcg multiway-tree postorder

我正在努力完成下面的Prolog作业,

Prolog使用普通树,而不是二叉树。一个例子是

     a(b,c,d(e,f,g))   where root a has 3 kids, as does kid d.

 It is possible to define both preorder and postorder for general trees, 
 although inorder of course makes no sense.

 For this assignment we are interested in postorder, which is defined as
 follows:

   to 'visit' a tree in postorder, 
      you visit the subtrees of the root, in left to right order,
      in postorder, and then you visit the root

 Thus the example above would yield the following postorder traversal:

        b c e f g d a

  Write Prolog code which will perform a postorder traversal of a Prolog
 tree constant.   Hint: you might use 'univ', or its cousins.

 Sample dialog:

 ?- postorder(a(b,c,d(e,f,g))).
 b c e f g d a    true

赞赏这个难题的任何帮助。

3 个答案:

答案 0 :(得分:2)

我为您提供了一个适用于更清晰的数据表示的解决方案,该解决方案仅通过模式匹配工作,不需要任何univ等。我统一呈现表格中的所有树{ {1}}。您的示例可以用以下表示形式编写:

tree(Node, Children)

现在,在描述节点的列表时,请考虑使用DCG。例如:

example(T) :-
        T = tree(a, [tree(b,[]),
                     tree(c,[]),
                     tree(d, [tree(e,[]),
                              tree(f,[]),
                              tree(g,[])])]).

具有上述定义及其结果的示例查询:

postorder(tree(Node, Children)) -->
        postorder_(Children),
        [Node].

postorder_([]) --> [].
postorder_([C|Cs]) -->
        postorder(C),
        postorder_(Cs).

我把它作为一个简单的练习,让这个DCG与你的树的表示一起工作(我不推荐,因为你不能单独通过模式匹配来描述解决方案,尽管显然可以使用不同的表示,如上所示)。

答案 1 :(得分:0)

tree :-
Tree= [1,
        [2,
       [4,
         [7, nil, nil],
         nil], 
       [5, nil, nil]],
        [3,
     [6,
       [8, nil, nil], 
       [9,nil, nil]], 
     nil]],

write('preorder    : '), preorder(Tree), nl,
write('inorder     : '), inorder(Tree), nl,
write('postorder   : '), postorder(Tree), nl,
write('level-order : '), level_order([Tree]),!.

preorder(nil).
preorder([Node, FG, FD]) :-
format('~w ', [Node]),
preorder(FG),
preorder(FD).


inorder(nil).
inorder([Node, FG, FD]) :-
inorder(FG),
format('~w ', [Node]),
inorder(FD).

postorder(nil).
postorder([Node, FG, FD]) :-
postorder(FG),
postorder(FD),
format('~w ', [Node]).


level_order([]).

level_order(A) :-
level_order_(A, U-U, S),
level_order(S).

level_order_([], S-[],S).

level_order_([[Node, FG, FD] | T], CS, FS) :-
format('~w ', [Node]),
append_dl(CS, [FG, FD|U]-U, CS1),
level_order_(T, CS1, FS).

level_order_([nil | T], CS, FS) :-
level_order_(T, CS, FS).


append_dl(X-Y, Y-Z, X-Z).

通过罗塞塔代码 - Tree Traversal in Prolog

代码有预购,有序,后序和等级顺序。

看看它们,您可能会觉得它们很有用。

输出:

?- tree.
 preorder    : 1 2 4 7 5 3 6 8 9 
 inorder     : 7 4 2 5 1 8 6 9 3 
 postorder   : 7 4 5 2 8 9 6 3 1 
 level-order : 1 2 3 4 5 6 7 8 9 
true .

修改:在tree查询结束时,我添加了!,因此它会停止第一个true.的回溯。否则,在true.之后,如果您输入;,则会一次又一次地获得true.

答案 2 :(得分:0)

postorder([]).
postorder(Tree):- Tree =..[Parent|Children] , myfun(Children), write(Parent),write(' ').
myfun([First|Next]):- atom(First), write(First), write(' '), myfun(Next).
myfun([First|Next]):- postorder(First),myfun(Next).
myfun([]).