在Prolog中镜像二叉树

时间:2018-11-28 04:22:47

标签: recursion prolog binary-tree

我有什么...

tree(nil).
tree(b(Left,_,Right)) :-
    tree(Left),
    tree(Right).

mirror(b(Left,Head,Right), NewTree) :-
    mirror(Left,NewLeft),
    mirror(Right,NewRight),
    NewTree = b(NewRight,Head,NewLeft).

我要查询的内容...

mirror(b(nil,a,b(nil,b,nil)), Result).

预期结果

Result = b(b(nil,b,nil),a,nil).

树b(Left,Right,Head)是mirror的第一个参数,NewTree是目标。 mirror(Left,NewLeft)从左侧递归并产生目标NewLeft,与Right相同。 NewTree是树b(NewRight,Head,NewLeft)。

我不确定为什么这种方法不起作用,请有人帮忙。

1 个答案:

答案 0 :(得分:1)

根据您当前的代码

tree(nil).
tree(b(Left,_,Right)) :-
    tree(Left),
    tree(Right).

mirror(b(Left,Head,Right), NewTree) :-
    mirror(Left,NewLeft),
    mirror(Right,NewRight),
    NewTree = b(NewRight,Head,NewLeft).

你非常亲近。

如史蒂文(Steven)的评论中所述

  

您缺少了mirror / 2的基本情况。输入树为零时,NewTree应该是什么?

非常有帮助。

在使用全部谓词之前,请先清除其他内容。
不需要树的谓词。

tree(nil).
tree(b(Left,_,Right)) :-
    tree(Left),
    tree(Right).

我不知道您是否向我们展示这是为了告诉您您知道一棵树是如何工作的或者是什么,但是对于其他阅读此谓词的人来说,答案并不需要它。

那只留下

mirror(b(Left,Head,Right), NewTree) :-
    mirror(Left,NewLeft),
    mirror(Right,NewRight),
    NewTree = b(NewRight,Head,NewLeft).

一个标准样式使用一个变量,该变量的作用类似于输入和输出,并且具有多种用法,即对于开始的变量,附加一个0,然后为每个后续的使用增加附加的数字,对结果不附加任何内容。

mirror(b(Left0,Head,Right0), NewTree) :-
    mirror(Left0,Left),
    mirror(Right0,Right),
    NewTree = b(Right,Head,Left).

下一步=/2仅在进行统一。可以这样重构

mirror(b(Left0,Head,Right0), b(Right,Head,Left)) :-
    mirror(Left0,Left),
    mirror(Right0,Right).

现在回到您的问题

由于树是递归结构,因此可以使用递归进行处理。在递归数据结构上工作的谓词需要一个基本子句和一个子句来执行递归。您已经有一个子句可以进行递归,但是只需要一个基本子句即可。

如果您在代码中使用SWI-Prolog gui跟踪器进行查询

mirror(b(nil,a,b(nil,b,nil)), Result).

您将会看到

enter image description here

当其中一个分支只是nil时,没有处理该情况的mirror / 2规则。

添加

mirror(nil,nil).

将解决您的问题。

?- mirror(b(nil,a,b(nil,b,nil)), Result).
Result = b(b(nil, b, nil), a, nil).

整个谓词。

mirror(nil,nil).

mirror(b(Left0,Head,Right0), b(Right,Head,Left)) :-
    mirror(Left0,Left),
    mirror(Right0,Right).