Prolog在树中查找元素的inorder位置(不使用列表)

时间:2017-10-16 22:00:24

标签: prolog

我试图通过inorder travel方法浏览二叉树 我的目标是找到树中特定键的出现 例如, 我有以下树:

t(t(t(nil,"d",t(nil,"g",nil)),"b",t(nil,"e",nil)),"a",t(t(nil,"f",t(nil,"h",nil)),"c",nil))

当我将使用我的inorder_finder时,我会得到以下内容: 对于“c”我会得到8 对于“d”我会得到1 因为“w”我会得到-1

我已经达到了以下代码:

inorder_finder(nil,_,_,0).

inorder_place(t(_,X,_),X,Count,Place) :-
    Place is Count+1.

inorder_place(t(L,_,R),Wanted,Count,Place) :-
        inorder_place(L,Wanted,Count+1,Place),
        Place<1, 
        inorder_place(R,Wanted,Count+1,Place),
        Place<1,
        Count = Count+1.

我调用以下谓词:

inorder_finder inorder_place(t(t(t(nil,"d",t(nil,"g",nil)),"b",t(nil,"e",nil)),"a",t(t(nil,"f",t(nil,"h",nil)),"c",nil)),"c",1,Place)

但此刻它不起作用。 (只是总是返回false) 任何想法?

更新:我已经根据我得到的评论更新了代码 - 它仍然返回false并且不能正常工作

1 个答案:

答案 0 :(得分:3)

评论中提到了最明显的错误,仍然存在的是:

  1. Place<1:我不明白为什么?地方的价值可能大于1。
  2. inorder_place:从未定义过......
  3. inorder_place(t(_,X,_),X,Count,Place):-Place is Count+1.:即使你找到了你需要的信,首先递归地枚举树的左分支然后放置想要的字母(见下面的答案)
  4. 我认为问题可以通过两个部分来解决,一个按顺序枚举所有节点,然后简单地遍历,直到找到正确的节点。虽然我没有遵循这个版本(即使它更清楚),因为使用简单混合解决方案它更有效,因为您可能不需要枚举所有节点。对于此次尝试,您尝试我认为您需要两个计数器 - 第一个计数器在调用inorder_find(..)时,例如进入时,第二个计数器将返回计数停止的位置,以便从树的右侧分支继续计数。
  5. inorder_finder inorder_place(...):仍然没有用于调用谓词的有效语法 - 它应该返回错误而不是false ...
  6. 我的实施:

    inorder_finder(nil,_,Count,Count,-1).
    
    inorder_finder(t(L,X,_),X,Count,Count2,Place):-
                    inorder_finder(L,X,Count,Count3,_),
                    Place is Count3+1,Count2 is Place.
    
    inorder_finder(t(L,X,R),Wanted,Count,Count2,Place):-
                    dif(X,Wanted),
                    inorder_finder(L,Wanted,Count,Count3,Place1),
                    Count4 is Count3+1,
                    inorder_finder(R,Wanted,Count4,Count2,Place2),
                    Place is max(Place1,Place2).
    

    示例:

    ?- inorder_finder(t(t(t(nil,"d",t(nil,"g",nil)),"b",t(nil,"e",nil)),"a",t(t(nil,"f",t(nil,"h",nil)),"c",nil)),"c",0,_,P).
    P = 8 ;
    false.
    
    ?- inorder_finder(t(t(t(nil,"d",t(nil,"g",nil)),"b",t(nil,"e",nil)),"a",t(t(nil,"f",t(nil,"h",nil)),"c",nil)),"W",0,_,P).
    P = -1.
    
    ?- inorder_finder(t(t(t(nil,"d",t(nil,"g",nil)),"b",t(nil,"e",nil)),"a",t(t(nil,"f",t(nil,"h",nil)),"c",nil)),"d",0,_,P).
    P = 1 ;
    false.