2011-01-22 6 views
1

私はすべての段階で現在のノードを取得するインオーダートラバーサルを実装しようとしています。 例えば:Prologを使ったバイナリツリーインオーダートラバーサル

?- getnodesinorder(tree(1,nil,nil),X). 
X = 1 ; 
false. 

?- getnodesinorder(tree(5,tree(4,tree(1,nil,tree(3,tree(2,nil,nil),nil)),nil),tree(6,nil,nil)),X). 
X = 1 ; 
X = 2 ; 
X = 3 ; 
X = 4 ; 
X = 5 ; 
X = 6 ; 
false. 

私は次のコードを試してみた:

getnodesinorder(tree(CurrentNode,nil,nil), CurrentNode). 
getnodesinorder(tree(X, Left, nil), CurrentNode) :- 
    getnodesinorder(Left, _), 
    CurrentNode is X. 
getnodesinorder(tree(X, nil, Right), CurrentNode) :- 
    CurrentNode is X, 
    getnodesinorder(Right, _). 
getnodesinorder(tree(X, Left, Right), CurrentNode) :- 
    getnodesinorder(Left, _), 
    CurrentNode is X, 
    getnodesinorder(Right, _). 

ベース(第一の例では動作します)もちろんそうするが、第二いずれかを実行しようとしたとき、私は

X=5; 
false 
を取得します結果として

となります。何故ですか?

答えて

3

あなたは左と右のサブツリーを処理し、それらの値と何もしていないため、エラーが発生します。getnodesinorder(Left, _)はちょうどそれらを捨てます。したがって、述語は先頭の要素のみを返します。

inorder(tree(_,L,_), X) :- inorder(L,X). 
inorder(tree(X,_,_), X). 
inorder(tree(_,_,R), X) :- inorder(R,X). 

例クエリ:

?- inorder(tree(5,tree(4,tree(1,nil,tree(3,tree(2,nil,nil),nil)),nil),tree(6,nil,nil)),X). 
X = 1 ; 
X = 2 ; 
X = 3 ; 
X = 4 ; 
X = 5 ; 
X = 6 ; 
false. 
1
[test] λ = cat test.pl 
append([], Ys, Ys). 
append([X|Xs], Ys, [X|Zs]) :- append(Xs, Ys, Zs). 

getnodesinorder(nil, []). 

getnodesinorder(tree(X, Left, Right), R) :- 
    getnodesinorder(Left,R1), 
    getnodesinorder(Right,R2), 
    append(R1,[X|R2],R). 

私の作品

?-getnodesinorder(tree(5,tree(4,tree(1,nil,tree(3,tree(2,nil,nil),nil)),nil),tree(6,nil,nil)),X). 
X = [1,2,3,4,5,6] ? 
yes 
+0

わかりましたが、(編集された上記参照)ということでしたが、今、私はちょうどX = 5を取得し、偽

は、ここでは、インオーダートラバースを行う方法です何らかの理由から。 – user550413

+0

私のサンプルを試してみてください。常にトレースを使用することを忘れないでください。 –

+0

はい、リストを使用しています。あなたのコードでは、Xはあなたが構築するリストであり、最終的にあなたはinorderのトラバーサルのリストを持っています。私は別のものが欲しい。私はXをすべての正しい値を取得する変数にします。この例のように、「;」と入力すると、次のX(インオーダーシーケンスの次の番号)を取得したい。 – user550413