f#访问树的根元素

时间:2011-04-28 11:20:53

标签: data-structures f# tree

我在F#中有一个规范树,即通过声明

type binaryTree = 
    | Leaf
    | Node of binaryTree * float * binaryTree

然后使用递归函数来生成树

let rec makeTree tree element = 
    match element, tree with
        | x, Leaf -> Node(Leaf,x,Leaf)
        | x, Node(l,y,r) -> Node(l,y, (makeTree r x))

这一切都很好。现在我想对树进行排序,以便在每个节点上,节点的值小于其所有子节点的值。我可以想象这样做。但是,我想接受树的第一个元素。也就是说,我想将树视为队列。我在树上看到的唯一例子是使用高阶函数来对树做一些事情,但是当我对它进行排序时,这似乎是浪费。

如何访问此树的根节点?

2 个答案:

答案 0 :(得分:2)

这个问题有点不清楚。据我所知,你将拥有一棵树,其中node的值小于其子节点的值。 (您可以通过编写树或通过编写构造它的不同函数来实现,这样就可以了。)

要实现一个采用树的第一个(最小)元素的函数,您需要删除根(最小),然后合并您将获得的两个树。这可以通过将两个根中较小的一个作为新根并递归地合并您将获得的新树来完成。以下代码片段可以解决这个问题:

let rec merge t1 t2 = 
  match t1, t2 with
  | Leaf, t | t, Leaf -> t // Merging a tree and a leaf gives the tree
  | (Node(ll, x1, lr) as t1), (Node(rl, x2, rr) as t2) ->
      // When merging two trees, take the smaller root as a new root
      // This gives you three new trees, so two of them must be recursively merged
      if x1 < x2 then Node(merge ll lr, x1, t2)
      else Node(t1, x2, merge rl rr)

let rec tryTake tree = 
  match tree with
  | Leaf -> None
  | Node(t1, y, t2) -> Some(y, merge t1 t2)

答案 1 :(得分:2)

这个怎么样:

let rootValue (Node(_,v,_)) = v

如果树为空,这将抛出异常。可替换地:

let tryGetRootValue = function
| Node(_,v,_) -> Some v
| _ -> None

这将始终成功,但会返回float option而不是float