【问题标题】:Find a element in binary tree in PROLOG在 PROLOG 中查找二叉树中的元素
【发布时间】:2018-12-19 17:43:13
【问题描述】:

我正在尝试使用 Prolog 来实现这一点,以在二叉树中查找元素。

elem1(tree(Element,void,void),Element).

elem1(tree(_Element,Left,Right),N) :-
  elem1(Left,N), 
  elem1(Right,N).

因为我认为 elem1 会检查我的树的根是否是我搜索的元素,并且这适用于此输出。

?- trace,elem1(tree(c,void,void),c).
Call: (9) elem1(tree(c, void, void), c) ? creep
Exit: (9) elem1(tree(c, void, void), c) ? creep
true

但是以这样的递归方式:

  ?- trace,elem1(tree(4,tree(1,void,void),tree(2,void,void)),1).
  Call: (9) elem1(tree(4, tree(1, void, void), tree(2, void, void)), 1) 
  creep
  Call: (10) elem1(tree(1, void, void), 1) ? creep
  Exit: (10) elem1(tree(1, void, void), 1) ? creep
  Call: (10) elem1(tree(2, void, void), 1) ? creep
  Call: (11) elem1(void, 1) ? creep
  Fail: (11) elem1(void, 1) ? creep
  Fail: (10) elem1(tree(2, void, void), 1) ? creep
  Redo: (10) elem1(tree(1, void, void), 1) ? creep
  Call: (11) elem1(void, 1) ? creep
  Fail: (11) elem1(void, 1) ? creep
  Fail: (10) elem1(tree(1, void, void), 1) ? creep
  Fail: (9) elem1(tree(4, tree(1, void, void), tree(2, void, void)), 1) ? 
  creep

  false.

似乎以正确的方式调用 (10) 并正确检查谓词,但在尝试扩展更多并给我失败之后。

我不知道为什么会这样,但是基本情况运行良好,所以我认为当找到一个元素时,退出并给我 true,因为基本谓词是有效的。

【问题讨论】:

标签: tree prolog logic


【解决方案1】:

您的代码稍作修改,以显示夸大了 AND (,) 的使用。

elem_01(tree(Element,void,void),Element).

elem_01(tree(_Element,Left,Right),N) :-
  (
    elem_01(Left,N)
  ,
    elem_01(Right,N)
  ).

例子:

?- elem_01(tree(4,tree(1,void,void),tree(2,void,void)),1).
false.

结果不正确。


使用 OR (;) 的更正版本。

elem_02(tree(Element,void,void),Element).

elem_02(tree(_Element,Left,Right),N) :-
  (
    elem_02(Left,N)
  ;
    elem_02(Right,N)
  ).

例子:

?- elem_02(tree(4,tree(1,void,void),tree(2,void,void)),1).
true ;
false.

在二叉树中正确找到1

?- elem_02(tree(4,tree(1,void,void),tree(2,void,void)),3).
false.

正确显示3 不在树中。


更正版本以显示使用两个子句而不是 OR (;)。

elem_03(tree(Element,void,void),Element).

elem_03(tree(_Element,Left,_),N) :-
    elem_02(Left,N).

elem_03(tree(_Element,_,Right),N) :-
    elem_02(Right,N).

例子:

?- elem_03(tree(4,tree(1,void,void),tree(2,void,void)),1).
true ;
false.

在二叉树中正确找到1

?- elem_03(tree(4,tree(1,void,void),tree(2,void,void)),3).
false.

正确显示3 不在树中。


在您的问题中,您将树显示为

elem1(tree(4,tree(1,void,void),tree(2,void,void)),1).

例如

  4
 / \
1   2

虽然它是一棵二叉树,但它不是一个正确的二叉树,其中左侧的键小于根,右侧的键大于根。

您想要这样的键的原因是您可以在搜索时使用比较,这样您就不必搜索整个树。

您的代码有效,但如果缺少值,它必须搜索整个树。如果您有一棵非常大的树并且没有匹配,那么如果您正确构建树并将比较添加到您的代码中,您会发现它丢失得更快。

这是适合您示例的树:

elem1(tree(2,tree(1,void,void),tree(4,void,void)),1).

例如

  2
 / \
1   4

【讨论】:

  • 非常详尽的答案。如果我希望只使用二叉树,我需要处理我的代码吗?我假设我只给我的查询提供二叉树,但是像你说我使用普通树之后
猜你喜欢
  • 1970-01-01
  • 2012-10-29
  • 1970-01-01
  • 1970-01-01
  • 2021-09-10
  • 1970-01-01
  • 2014-03-05
  • 1970-01-01
相关资源
最近更新 更多