将邻接列表转换为递归格式
convert list of adjacencies to recursive format
给定一棵邻接列表格式的二叉树,例如 [1-8,1-2,...]
列表中的元素没有任何特定顺序。
给定树的根,需要将列表转换为递归格式 t(L,Root,R)。其中 L 和 R 是树本身或 nil。
这是我试过的:
% convert binary tree from adjacencies list to recursive term format.
% make_tree(AdjList, Root, Tree)
make_tree([],Root,t(nil,Root,nil)):-!.
make_tree([Root-X],Root,t(X,Root,nil)).
make_tree([Root-X],Root,t(nil,Root,X)):-!.
make_tree(_,nil,nil):-!.
make_tree(N,Root,t(L,Root,R)):-
find_kids(N,Root,C,S),
reorder(C,[C1,C2]),
make_tree(S,C1,L), make_tree(S,C2,R).
% reorder 2 out of 2
reorder([X,Y],[Y,X]).
reorder([X,Y],[X,Y]).
% find children and remove them from list of nodes
find_kids(L,Root,[C1,C2],R):-
find_children(L,Root,[C1,C2|_],R).
find_children([Root-Y|Xs],Root,[Y|T],Acc):-
find_children(Xs,Root,T,Acc).
find_children([X-Y|Xs],Root,R,[X-Y|Acc]):-
X \= Root,
find_children(Xs,Root,R,Acc).
find_children([],_,[nil,nil],[]).
考虑以下二叉树及其任意邻接表:
% 0
% / \
% 1 2
% / \ / \
% 3 4 5 6
% / \ \
% 7 8 9
adj_list([1-3,0-2,1-4,5-9,3-7,2-5,2-6,3-8,0-1]).
要获取节点的子节点,您可以使用以下谓词:
find_children(Root, List, Children, Rest) :-
partition({Root}/[X-_]>>(X=Root), List, Children0, Rest),
maplist([Root-Child, Child]>>true, Children0, Children).
示例:
?- adj_list(List), find_children(3, List, Children, Rest).
List = [1-3, 0-2, 1-4, 5-9, 3-7, 2-5, 2-6, 3-8, ... - ...],
Children = [7, 8],
Rest = [1-3, 0-2, 1-4, 5-9, 2-5, 2-6, 0-1].
?- adj_list(List), find_children(5, List, Children, Rest).
List = [1-3, 0-2, 1-4, 5-9, 3-7, 2-5, 2-6, 3-8, ... - ...],
Children = [9],
Rest = [1-3, 0-2, 1-4, 3-7, 2-5, 2-6, 3-8, 0-1].
?- adj_list(List), find_children(4, List, Children, Rest).
List = Rest, Rest = [1-3, 0-2, 1-4, 5-9, 3-7, 2-5, 2-6, 3-8, ... - ...],
Children = [].
要从给定根构建所有可能的二叉树,您可以使用以下代码:
% trees(+Root, -Tree)
trees(Root, Tree) :-
adj_list(List),
make_tree(Root, List, _Rest, Tree).
% make_tree(+Root, +List, -Rest, -Tree)
make_tree(Root, List, Rest, Tree) :-
find_children(Root, List, Children, Rest0),
make_tree(Children, Root, Rest0, Rest, Tree).
make_tree([], Root, List, List, t(nil, Root, nil)).
make_tree([X], Root, List, Rest, Tree) :-
make_tree(X, List, Rest, Subtree),
( Tree = t(Subtree, Root, nil)
; Tree = t(nil, Root, Subtree) ).
make_tree([X,Y], Root, List, Rest, Tree) :-
make_tree(X, List, Rest0, Subtree1),
make_tree(Y, Rest0, Rest, Subtree2),
( Tree = t(Subtree1, Root, Subtree2)
; Tree = t(Subtree2, Root, Subtree1) ).
示例:
?- trees(4, T).
T = t(nil, 4, nil).
?- trees(3, T).
T = t(t(nil, 7, nil), 3, t(nil, 8, nil)) ;
T = t(t(nil, 8, nil), 3, t(nil, 7, nil)).
?- trees(5, T).
T = t(t(nil, 9, nil), 5, nil) ;
T = t(nil, 5, t(nil, 9, nil)) ;
false.
?- trees(2, T).
T = t(t(t(nil, 9, nil), 5, nil), 2, t(nil, 6, nil)) ;
T = t(t(nil, 6, nil), 2, t(t(nil, 9, nil), 5, nil)) ;
T = t(t(nil, 5, t(nil, 9, nil)), 2, t(nil, 6, nil)) ;
T = t(t(nil, 6, nil), 2, t(nil, 5, t(nil, 9, nil))) ;
false.
给定一棵邻接列表格式的二叉树,例如 [1-8,1-2,...] 列表中的元素没有任何特定顺序。 给定树的根,需要将列表转换为递归格式 t(L,Root,R)。其中 L 和 R 是树本身或 nil。
这是我试过的:
% convert binary tree from adjacencies list to recursive term format.
% make_tree(AdjList, Root, Tree)
make_tree([],Root,t(nil,Root,nil)):-!.
make_tree([Root-X],Root,t(X,Root,nil)).
make_tree([Root-X],Root,t(nil,Root,X)):-!.
make_tree(_,nil,nil):-!.
make_tree(N,Root,t(L,Root,R)):-
find_kids(N,Root,C,S),
reorder(C,[C1,C2]),
make_tree(S,C1,L), make_tree(S,C2,R).
% reorder 2 out of 2
reorder([X,Y],[Y,X]).
reorder([X,Y],[X,Y]).
% find children and remove them from list of nodes
find_kids(L,Root,[C1,C2],R):-
find_children(L,Root,[C1,C2|_],R).
find_children([Root-Y|Xs],Root,[Y|T],Acc):-
find_children(Xs,Root,T,Acc).
find_children([X-Y|Xs],Root,R,[X-Y|Acc]):-
X \= Root,
find_children(Xs,Root,R,Acc).
find_children([],_,[nil,nil],[]).
考虑以下二叉树及其任意邻接表:
% 0
% / \
% 1 2
% / \ / \
% 3 4 5 6
% / \ \
% 7 8 9
adj_list([1-3,0-2,1-4,5-9,3-7,2-5,2-6,3-8,0-1]).
要获取节点的子节点,您可以使用以下谓词:
find_children(Root, List, Children, Rest) :-
partition({Root}/[X-_]>>(X=Root), List, Children0, Rest),
maplist([Root-Child, Child]>>true, Children0, Children).
示例:
?- adj_list(List), find_children(3, List, Children, Rest).
List = [1-3, 0-2, 1-4, 5-9, 3-7, 2-5, 2-6, 3-8, ... - ...],
Children = [7, 8],
Rest = [1-3, 0-2, 1-4, 5-9, 2-5, 2-6, 0-1].
?- adj_list(List), find_children(5, List, Children, Rest).
List = [1-3, 0-2, 1-4, 5-9, 3-7, 2-5, 2-6, 3-8, ... - ...],
Children = [9],
Rest = [1-3, 0-2, 1-4, 3-7, 2-5, 2-6, 3-8, 0-1].
?- adj_list(List), find_children(4, List, Children, Rest).
List = Rest, Rest = [1-3, 0-2, 1-4, 5-9, 3-7, 2-5, 2-6, 3-8, ... - ...],
Children = [].
要从给定根构建所有可能的二叉树,您可以使用以下代码:
% trees(+Root, -Tree)
trees(Root, Tree) :-
adj_list(List),
make_tree(Root, List, _Rest, Tree).
% make_tree(+Root, +List, -Rest, -Tree)
make_tree(Root, List, Rest, Tree) :-
find_children(Root, List, Children, Rest0),
make_tree(Children, Root, Rest0, Rest, Tree).
make_tree([], Root, List, List, t(nil, Root, nil)).
make_tree([X], Root, List, Rest, Tree) :-
make_tree(X, List, Rest, Subtree),
( Tree = t(Subtree, Root, nil)
; Tree = t(nil, Root, Subtree) ).
make_tree([X,Y], Root, List, Rest, Tree) :-
make_tree(X, List, Rest0, Subtree1),
make_tree(Y, Rest0, Rest, Subtree2),
( Tree = t(Subtree1, Root, Subtree2)
; Tree = t(Subtree2, Root, Subtree1) ).
示例:
?- trees(4, T).
T = t(nil, 4, nil).
?- trees(3, T).
T = t(t(nil, 7, nil), 3, t(nil, 8, nil)) ;
T = t(t(nil, 8, nil), 3, t(nil, 7, nil)).
?- trees(5, T).
T = t(t(nil, 9, nil), 5, nil) ;
T = t(nil, 5, t(nil, 9, nil)) ;
false.
?- trees(2, T).
T = t(t(t(nil, 9, nil), 5, nil), 2, t(nil, 6, nil)) ;
T = t(t(nil, 6, nil), 2, t(t(nil, 9, nil), 5, nil)) ;
T = t(t(nil, 5, t(nil, 9, nil)), 2, t(nil, 6, nil)) ;
T = t(t(nil, 6, nil), 2, t(nil, 5, t(nil, 9, nil))) ;
false.