我知道如何在过程化语言(如C++、Java等)中执行二叉搜索树的范围查询,但我觉得将其转换为Prolog语言比较困难。
过程化语言的实现方式应该是:
非常感谢大家。
过程化语言的实现方式应该是:
http://www.geeksforgeeks.org/print-bst-keys-in-the-given-range/
任何提示如何将其转换为Prolog范式吗?非常感谢大家。
http://www.geeksforgeeks.org/print-bst-keys-in-the-given-range/
任何提示如何将其转换为Prolog范式吗?你引用网站上的声明性描述可以直接翻译为Prolog:
1)如果关键字大于k1,则在左子树中递归调用。
Prolog翻译:
bst(tree(Key, Left, Right), K1, K2, Value) :-
Key > K1,
bst(Left, K1, K2, Value).
2) 如果 key 在范围内,则打印该键。
我们不使用像“print”这样的不纯谓词,因为它们是不可逆的。相反,我们使用 Prolog 为我们在顶层报告绑定:
bst(tree(Key, _, _), K1, K2, Key) :- between(K1, K2, Key).
3) 如果key小于k2,则在右子树中递归调用。
我将这个留作练习。
查询
?- bst(Tree, K1, K2, Value).
回溯时,该查询将返回给定范围内的Value
绑定。
如果使用约束,则可以在所有方向上使用此谓词,并且还可以生成包含值的树。
在编程语言C++或Java中,你可以做与此相同的事情。 只要你写了所需的最小代码(在C++中),就有非常高的机会得到正确的结果。这通常涉及到递归定义,例如:
// pseudocode - Elem must implement operator<
struct BST<Elem> {
bool find(const Elem e) { return find(root, e) }
private:
bool find(Node n, Elem e) {
if (!n) return false;
if (n.payload() == e) return true;
return n.payload() < e ? find(n.left) : find(n.right);
}
}
相同的搜索可以通过手动展开堆栈,利用(呃)堆栈,然后迭代来编写。
stack<Node> stack; stack.push(root);
while (!stack.isEmpty()) {
Node n = stack.pop();
// check found, return true
// push left or right...
}
t(Payload,Left,Right)
,默认值为t(0,-,-)
,则可以执行以下操作:% note: untested
bst(t(Payload,_,_), Payload). % found
bst(t(Payload,L,R), Sought) :- Sought @< Payload -> bst(L, Sought) ; bst(R, Sought).
// live code here
void lqXDotScene::dump(QString m) const {
qDebug() << m;
cg->depth_first([&](Gp t) { qDebug() << "graph" << gvname(t) << CVP(find_graph(t)); });
qDebug() << "nodes";
cg->for_nodes([&](Np n) {
qDebug() << "node" << gvname(n) << CVP(find_node(n));
cg->for_edges_out(n, [&](Ep e) {
qDebug() << "edge" << gvname(e) << CVP(find_edge(e)) << "to" << gvname(e->node) << CVP(find_node(e->node));
});
});
}
这一行
cg->depth_first([&](Gp t) { qDebug() << "graph" << gvname(t) << CVP(find_graph(t));
执行一个完整的访问。find_graph、find_等都是成员函数:lambda非常强大。
setof/3
这样的全解决方案谓词。 - mat