Prolog中二进制搜索树的范围查询

时间:2013-12-09 09:01:30

标签: prolog binary-search-tree

我知道如何以程序方式(也就是C ++,Java等)对BST执行范围查询,但我发现很难转换为Prolog语言。

程序方式应该是:

http://www.geeksforgeeks.org/print-bst-keys-in-the-given-range/

任何提示如何将其转换为Prolog范例?

非常感谢大家

2 个答案:

答案 0 :(得分:2)

您引用的网站的声明性描述可以直接翻译为Prolog:

1)如果 key 大于 k1 ,则以递归方式调用左子树。

Prolog翻译:

bst(tree(Key, Left, Right), K1, K2, Value) :-
        Key > K1,
        bst(Left, K1, K2, Value).

2)如果在范围内,则打印该键。

我们不使用像“print”这样的不纯谓词,因为它们不可逆。相反,我们使用Prolog报告我们的顶层绑定:

bst(tree(Key, _, _), K1, K2, Key) :- between(K1, K2, Key).

3)如果 key 小于 k2 ,则递归调用右子树。

我将此作为练习。

查询

?- bst(Tree, K1, K2, Value).

将产生给定范围内Value的回溯绑定。

如果使用约束,则可以在所有方向上使用此谓词,也可以生成包含值的树。

答案 1 :(得分:-1)

与C ++或Java完全相同。 非常很有可能你会得到正确的结果,假设(用C ++表示),你编写了所需的 minimal 代码。该帐户通常用于递归定义:类似

// 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);
  }
}

可以手动编写相同的搜索,通过(duh)堆栈展开堆栈,然后迭代

stack<Node> stack; stack.push(root);
while (!stack.isEmpty()) {
  Node n = stack.pop();
  // check found, return true
  // push left or right...
}

在Prolog中,堆栈被“嵌入”在语言中:只需说明解决方案“形式”是什么:假设像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).

关于C ++的注释:我已经在github(loqt)上上传了 raw 指针模型上的声明性非侵入式C ++接口示例(Agraph_t *和朋友) 。使用该接口,现在我们在C ++中使用lambda非常简单:

// 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_ etc是成员函数:lambda它的非常功能强大。