tree - Prolog中的有序树遍历

标签 tree prolog

我是 Prolog 新手,我正在尝试编写一个有序树遍历,其中给出了一系列事实,例如:

leftSubtree(9, 7).
leftSubtree(7, 1).
leftSubtree(1, -2).
leftSubtree(11, 9).
leftSubtree(16, 13).
leftSubtree(3, 2).
rightSubtree(9, 11).
rightSubtree(7, 6).
rightSubtree(1, 3).
rightSubtree(11, 16).
rightSubtree(16, 19).

我可以使用 inOrder(9,X)。按顺序打印出一棵树。我尝试使用以下有效的代码,但希望有更简单的东西。任何提示或帮助将不胜感激。

inOrder(Root, X):-
   \+ leftSubtree(Root,Left),
   \+ rightSubtree(Root,Left) ->
   X = [Root];
   leftSubtree(Root,Left), 
   rightSubtree(Root,Right)->
   inOrder(Left, LeftNode),
   inOrder(Right, RightNode),
   append(LeftNode,[Root|RightNode],X);
   leftSubtree(Root,Left), 
   inOrder(Left, LeftNode),
   append(LeftNode,[Root],X);
   rightSubtree(Root,Right)->
   inOrder(Right, RightNode),
   append([Root],RightNode,X).

最佳答案

您的代码可以得到简化,避免负面测试,并使用 Prolog 的一些自反性。

inOrder(Root, [Left, Root, Right]) :-
  inOrder(leftSubtree, Root, Left),
  inOrder(rightSubtree, Root, Right).

inOrder(BranchToExplore, Root, Subtree) :-
   call(BranchToExplore, Root, Branch)
   ->  inOrder(Branch, Subtree)
   ;   Subtree = [].

这将恢复树的结构,作为嵌套的三元列表,然后一次调用 flatten/2 就足以使其扁平,如下所示您原来的要求。

?- inOrder(8, Tree), flatten(Tree, L).
Tree = [[[[[], -2, []], 1, [[[], 2, []], 3, []]], 5, [[], 6, []]], 8, [[[], 9, [[], 10|...]], 11, [[[], 13|...], 16, [...|...]]]],
L = [-2, 1, 2, 3, 5, 6, 8, 9, 10|...].

如果您的 Prolog 没有 call/N,您可以使用 univ 构建一个可调用术语:

inOrder(BranchToExplore, Root, Subtree) :-
  ( Callable =.. [BranchToExplore, Root, Branch], call(Callable) )
  ->  inOrder(Branch, Subtree)
  ;   Subtree = [].

如果我们交换 Left 和 Root,我们就会得到更有用的 preOrder 表示形式:preOrder(Root, [Root, Left, Right]) :- ...

在 preOrder 中拥有树的结构对于进一步的处理很有用:一个“准备就绪”并且在 SWI-Prolog 中有用的实现,它是 XML,其中树表示为元素(标签、属性、子树),并且可以由 library(xpath) 处理。更改 inOrder/2 和 inOrder/3 来恢复 XML 可能是一个有用的练习。

关于tree - Prolog中的有序树遍历,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9090556/

相关文章:

list - Prolog 添加 N 到 0 到列表

performance - 是否有库/技术来收集 Prolog 中最佳子句排序的统计信息?

parsing - prolog解析操作问题

mysql - 如何检索mysql中所有记录的树节点数?

c++ - 在 C++ 中使用 STL 实现图形和树的良好且稳定的方法是什么?

scala - 在 Scala 中制作一个非常基本的二叉树

序言和翻译命题逻辑

prolog - 快速在 Prolog 中运行

extjs - 在 ExtJS 拖放树上,使用 drop 或 beforedrop 监听器似乎不会触发

c++ - 不使用堆栈的 TBB task_groups