Prolog中的二叉树

时间:2011-04-21 14:12:30

标签: dictionary tree prolog binary-tree

我需要编写一个prolog程序,从键盘读取这样的正数,直到用户写'stop'并构建一个没有重复的二进制字典。

我试试:

:-dynamic tree/1.

 run:-
     retractall(tree(_)),
     write('Input N '), read(N),
     insert(N,empty,T),
     assert(tree(T)),
     start(N),nl,
     tree(T),write(T),!.

start(stop):-!.
start(N):-
      N \= stop,
      tree(T),
      insert(N,T,NewTree),
      assert(tree(NewTree)),
      write('Input N '), read(M),
      start(M).

insert(NewItem,empty,tree(NewItem,empty,empty)):- !.
insert(NewItem,tree(Element,Left,Right),tree(Element,NewLeft,Right)):-
                                                                  NewItem @< Element,
                                                                  !,insert(NewItem,Left,NewLeft).

insert(NewItem,tree(Element,Left,Right),tree(Element,Left,NewRight)):-
                                                                  insert(NewItem,Right,NewRight).

任何人都可以帮助我吗?

1 个答案:

答案 0 :(得分:1)

这里有两个错误。首先,第一个元素被插入两次,因为在run的主体中显式调用insert,而对start的调用也会调用insert。而不是这样做,你需要从记录空树开始。其次,仅查询当前正在记录哪个树是不够的,您需要删除以前版本的树并记录当前树。

解决这两个错误导致以下解决方案:

:-dynamic tree/1.

 run:-
     retractall(tree(_)),
     write('Input N '), read(N),
     assert(tree(empty)),  % 1. initially the tree is empty
     start(N),nl,
     tree(T),write(T),!.

start(stop):-!.
start(N):-
      N \= stop,
      retract(tree(T)), % 2. changed here
      insert(N,T,NewTree),
      assert(tree(NewTree)),
      write('Input N '), read(M),
      start(M).

insert(NewItem,empty,tree(NewItem,empty,empty)):- !.
insert(NewItem,tree(Element,Left,Right),tree(Element,NewLeft,Right)):-
       NewItem @< Element,
       !,insert(NewItem,Left,NewLeft).

insert(NewItem,tree(Element,Left,Right),tree(Element,Left,NewRight)):-
        insert(NewItem,Right,NewRight).

稍微不同的是,您可能会问自己是否真的需要执行所有这些断言/撤消,因为您可以将当前构造的树作为起始谓词的参数传递。

消除断言和缩回提供以下版本:

run:-
     write('Input N '), read(N),
     start(N, empty, T),nl,
     write(T).

start(stop, T, T):-!.
start(N, CurTree, FinalTree):-
      N \= stop,
      insert(N,CurTree,NewTree),
      write('Input N '), read(M),
      start(M, NewTree, FinalTree).

insert(NewItem,empty,tree(NewItem,empty,empty)):- !.
insert(NewItem,tree(Element,Left,Right),tree(Element,NewLeft,Right)):-
       NewItem @< Element,
       !,insert(NewItem,Left,NewLeft).

insert(NewItem,tree(Element,Left,Right),tree(Element,Left,NewRight)):-
        insert(NewItem,Right,NewRight).

最后,观察开始的第一个子句中的cut和第一个和第二个参数的stop的预期用法,当第三个参数被释放时,使得显式检查N \ =停止冗余。这为我们提供了解决方案的最终版本:

run:-
     write('Input N '), read(N),
     start(N, empty, T),nl,
     write(T).

start(stop, T, T):-!.
start(N, CurTree, FinalTree):-
      insert(N,CurTree,NewTree),
      write('Input N '), read(M),
      start(M, NewTree, FinalTree).

insert(NewItem,empty,tree(NewItem,empty,empty)):- !.
insert(NewItem,tree(Element,Left,Right),tree(Element,NewLeft,Right)):-
       NewItem @< Element,
       !,insert(NewItem,Left,NewLeft).
insert(NewItem,tree(Element,Left,Right),tree(Element,Left,NewRight)):-
        insert(NewItem,Right,NewRight).