Haskell树分裂:有人可以解释这一行吗?

时间:2013-04-28 20:29:45

标签: haskell

split s (Root x lst rst)
 | s < x = let (nlt, nrt) = split s lst in
     (nlt, Root x nrt rst)

有人可以解释一下这行吗?我并没有真正得到let部分。

我试着考虑一下,我不知道我是否做对了: 我们将(nlt, nrt)绑定到split s lst的结果; split s lst本身将是(nlt, Root x nrt rst)

是吗?

这是完整的代码:

split :: Ord a => a -> Tree a -> (Tree a, Tree a)
split _ Empty = (Empty, Empty)
split s (Root x lst rst)
 | s < x = let (nlt, nrt) = split s lst in
     (nlt, Root x nrt rst)
 | s > x = let (nlt, nrt) = split s rst in
         (Root x lst nlt, nrt)

1 个答案:

答案 0 :(得分:44)

  

我们将(nlt, nrt)绑定到split s lst

的结果

是的 - split s lst是一对,我们将名称nltnrt分配给该对的两个元素。

  

split s lst本身将是(nlt, Root x nrt rst)

不,split s (Root x lst rst)(整个功能的结果)将为(nlt, Root x nrt rst)

但整个功能的作用是什么?

split :: Ord a => a -> Tree a -> (Tree a, Tree a)
split _ Empty = (Empty, Empty)
split s (Root x lst rst)
 | s < x = let (nlt, nrt) = split s lst in
     (nlt, Root x nrt rst)
 | s > x = let (nlt, nrt) = split s rst in
         (Root x lst nlt, nrt)

让我们试试一些样本数据:

> split 300 (Root 512 (Root 256 (Root 128 Empty Empty) (Root 384 Empty Empty)) Empty)
(Root 256 (Root 128 Empty Empty) Empty,Root 512 (Root 384 Empty Empty) Empty)

因此我们选择了一个以512为根的树,以及比左子树中的所有项小的树,并将其拆分,以便第一个树由300以下的条目组成,第二个树在第二个树中组成300以上。看起来像这样:

enter image description here

有问题的线如何运作?

首先让我们用扩展名重写代码:

split :: Ord a => a -> Tree a -> (Tree a, Tree a)
split _ Empty = (Empty, Empty)
split s (Root x left_subtree right_subtree)
 | s < x = let (new_left_tree, new_right_tree) = split s left_subtree in
     (new_left_tree, Root x new_right_tree right_subtree)
 | s > x = let (new_left_tree, new_right_tree) = split s right_subtree in
         (Root x left_subtree new_left_tree, new_right_tree)

警卫|s < x表示我们认为此x应该在右侧。

首先,我们拆分左子树split s left_subtree,给我们一个new_left_treenew_right_treenew_left_tree是应该留下的内容,但new_right_treex和原始right_subtree合并,以构成{{1}右侧的位1}}。

我们可以从中学到什么功能?

由于s位于right_subtree的左侧,s属于x,因此该函数假设树已经在Root x l r的意义上排序了,l中的所有内容均低于xr中的所有内容均高于x

left_subtree被拆分,因为其中一些可能小于s而其他位超过s

现在属于右侧的split s left_subtree部分(因为它超过s)称为new_right_tree,因为整个left_subtree小于{{ 1}}和x,所有right_subtree仍应位于new_right_treex的左侧。这就是为什么我们让right_subtree成为对中的右手答案(以及对中左侧的Root x new_right_tree right_subtree)。

这是一张前后图:

enter image description here

为什么没有更多的描述性名称呢?

好问题。我们这样做:

new_left_tree

好吧,我认为这回答了我的问题:有时描述性的名字也会让人感到困惑!