Он доходя, потому что у вас есть два рекурсивных положения, каждый из которых идет только на одну сторону дерева. У вас также есть два базовых блока, хотя второй не нужен.
Таким образом, вы должны удалить второе предложение и присоединиться к двум рекурсивным предложениям только в одном предложении, которое добавляет результаты из обеих ветвей.
Например:
preOrder(nil, []).
preOrder(node(X, L, R), [X|T]) :-
preOrder(L, LT),
append(LT, RT, T),
preOrder(R, RT).
Вы можете также использовать аккумулятор для обхода:
preOrder(Tree, List):-
preOrder(Tree, [], RList),
reverse(RList, List).
preOrder(nil, List, List).
preOrder(node(X, L, R), List, NList) :-
preOrder(L, [X|List], MList),
preOrder(R, MList, NList).
Обратите внимание, что, как сказал один из комментаторов, эти определения для предзаказа нет не работает право генерировать деревья дали ВТП.
Вы можете использовать DCGs определить процедуру, которая будет обратимым, внутренне используя открытые списки:
preOrder(nil)-->[].
preOrder(node(X, L, R))-->[X], preOrder(L), preOrder(R).
И вы бы назвали его помощью phrase/2
:
?- phrase(preOrder(node(1, node(2, node(3,nil,nil), node(4,nil,nil)), node(5,nil,nil))), L).
L = [1, 2, 3, 4, 5].
Первый вариант: для всех непустые списки 'L' и' T' uninstantiated, 'preOrder (T, L)' не заканчиваются. Вторая версия: Циклы также для 'L = []'. – false
Правда, но @OP хочет пересечь данное дерево, а не генерировать деревья из обходного списка. – gusbro