【发布时间】:2013-02-22 00:23:21
【问题描述】:
我在 OCaml 中使用列表实现binary heap,只是为了提高我的 OCaml 技能。
感觉list使用起来很吃力,苦苦挣扎了2天,不得不来这里寻求建议和提示。
这是我目前的想法
显然,我不能使用原始的array based 算法来使用列表来实现它。
我想使用的是binary tree。我保留了invariant,即节点应该大于任何级别低于其的节点。
我大致弄清楚了如何实现insert,虽然我不确定它是否正确。
对于二叉树,每个节点都有two children、value 和size n,这是它拥有的offsprings 的总数。这个n 用于平衡树。
当插入x 时,我与一个节点(从根,递归)进行比较。假设x < the value of the node,那么
如果节点的一个或两个子节点是Leaf,那么我将x 插入到那个叶子位置。
如果节点的孩子none是Leaf,那么我会选择n小于的孩子然后recursively insert。
这是我的代码
type 'a heap =
| Node of 'a * 'a heap * 'a heap * int
| Leaf
exception EmptyHeapException
let create_heap () = Leaf;;
let rec insert x = function
| Leaf -> Node (x, Leaf, Leaf, 0)
| Node (v, l, r, n) ->
let (stay, move) = if x > v then (x, v) else (v, x)
in
match (l, r) with
| (Leaf, Leaf) ->
Node (stay, Node (move, Leaf, Leaf, 0), Leaf, 1)
| (Leaf, _) ->
Node (stay, Node (move, Leaf, Leaf, 0), r, n+1)
| (_, Leaf) ->
Node (stay, l, Node (move, Leaf, Leaf, 0), n+1)
| (Node (_, _, _, n1), Node (_, _, _, n2)) ->
if n1 <= n2 then
Node (stay, (insert move l), r, n1+1)
else
Node (stay, l, (insert move r), n2+1);;
好的,我有以下问题。
- 我是否朝着正确的方向前进?我的想法或实现是否正确?
- 我在实现
get_top函数时遇到了困难。我不知道如何继续。有什么提示吗? - ocaml 电池实现了高效的batHeap.ml。我看过,但我觉得它的方式与我的完全不同,我无法理解。谁能帮我理解一下?
【问题讨论】:
-
为什么不直接写
x > v而不是compare x v > 0? -
@AndrejBauer 是的,你是对的。我刚开始的想法是我应该有一个
compare函数作为堆、排序等的参数,因为某些用户可能不使用Pervasives.compare。 -
我明白了。在这种情况下,您可能会对使用仿函数感兴趣。顺便问一下,你看过标准库中 OCaml
Map模块的源代码吗?它有一个平衡二叉搜索树的实现,就像你正在实现的那样。 -
@AndrejBauer 谢谢。实际上我还没有学过仿函数,但是会学的:D
-
你为什么说你在尝试使用列表,你的代码中没有列表?
标签: functional-programming ocaml