Tree 如何在Prolog中从多路树中删除元素

Tree 如何在Prolog中从多路树中删除元素,tree,prolog,Tree,Prolog,我和我的朋友们都在为这项任务苦苦挣扎。在任何其他语言中,这都很容易 我们尝试将树转换为列表,删除一个元素,然后构建一棵树。从列表到树的构建部分我们不知道该怎么做 我将如何使用这棵树: tree(1,[tree(6,[tree(7,[])])), 树(3,[]), 树(2,[树(4,[]), 树(5,[])) ]) 非常感谢任何提示或解决方案。Prolog变量是不可变的-它们的值不能更改。 所以,如果你想改变一棵树,比如说三向树,你有一个谓词来声明你想要的改变 使用新值替换特定节点的简单非递归情

我和我的朋友们都在为这项任务苦苦挣扎。在任何其他语言中,这都很容易


我们尝试将树转换为列表,删除一个元素,然后构建一棵树。从列表到树的构建部分我们不知道该怎么做

我将如何使用这棵树:

tree(1,[tree(6,[tree(7,[])])),
树(3,[]),
树(2,[树(4,[]),
树(5,[]))
])

非常感谢任何提示或解决方案。

Prolog变量是不可变的-它们的值不能更改。 所以,如果你想改变一棵树,比如说三向树,你有一个谓词来声明你想要的改变

使用新值替换特定节点的简单非递归情况:

replace_left_node(tree(_,B,C), NewNode, tree(NewNode, B, C).
replace_right_node(tree(A,B,_), NewNode, tree(A, B, NewNode).
replace_middle_node(tree(A,_,C), NewNode, tree(A, NewNode, C).
对于recursif情况,必须更详细地指定更改。例如,在具有左、右子树和中间值的节点值的树中,用值B替换具有值A的节点值,例如:

replace(a, b).           % replace the value a by value b
replace(X, X) :- X \= a. % otherwise use the same value unchanged
递归情况是对左、右子树执行相同的操作

replace_recursively(terminal, terminal) % this is the tree leaf
replace_recursively(tree(L, V, R), tree(L1, V1, R1)) :-
    replace(V, V1),             % handle the node value
    replace_recursively(L, L1), % handle left sub-tree
    replace_recursively(R, R1). % handle right sub-tree

这回答了你的问题吗?你还需要什么?

好的,根据你在评论中给出的例子,我能更好地理解。我给出了一个示例,用于删除具有给定值Elm的节点。这是一个双递归,一个用于处理函子树,另一个用于处理列表

remove_elem_from_tree(Elm, tree(V, Nodes), tree(V,Nodes1) ):-
    Elm \= V,
    remove_elem_from_list(Elm, Nodes, Nodes1).
    
    remove_elem_from_list(_, [], []).
    remove_elem_from_list(E, [X|Xs], [Y|Ys]) :-
        remove_elem_from_tree(E, X, Y), !, 
        remove_elem_from_list(E, Xs, Ys).
    remove_elem_from_list(E, [_|Xs], Ys) :-
        remove_elem_from_list(E, Xs, Ys).
        
所以运行的示例是:删除节点4

?- remove_elem_from_tree(4, tree(1, 
        [   tree(6, [tree(7, [])]),
            tree(3, []),
            tree(2, [tree(4, []),tree(5, [])])
        ]
      ), Result).

Result = tree(1,[tree(6,[tree(7,[])]),tree(3,[]),tree(2,[tree(5,[])])])
节点4位于给定树中的节点2之下。它将被删除,节点2现在拥有唯一的子节点5


这个答案对你和你的朋友有帮助吗?

你尝试了什么?我们尝试将树转换为列表,删除一个元素,然后构建一棵树。从列表到树的构建部分我们不知道如何构建,但您不需要首先将其转换为列表。您可以递归地创建新节点,有点类似于手指树。是否创建新节点?那么从我删除的节点我需要从我删除的节点创建新节点?我将如何处理这棵树:树(1,[树(6,[树(7,[]))]、树(3,[])、树(2,[树(4,[])、树(5,[]))谢谢你的回答!但是我们找到了二叉树的解决方案。如何解决多路树的问题?你必须把二叉树的问题扩展到多路树。从定义什么是多路树开始,这对这里的所有读者都有好处。也许是这样。然后用Prolog术语仔细定义一个示例树。如果arity在每个节点都是可变的,那么您可能有一个术语列表。等等。