从列表中创建随机堆

时间:2018-01-07 16:58:24

标签: list haskell heap

我正在哈斯克尔大学学习一些大学,我坚持这一点。数据类型如下:

data Heap a = Empty | Node a (Heap a) (Heap a)

(在本练习中Heap a始终是最小 - 最大堆,因此树中偶数级别的每个节点都小于其所有后代,而树中奇数级别的每个节点都是比它的所有后代都要大。)

问题:

  

" randomHeap :: [a] -> IO (Heap a)生成一个随机堆,包含参数列表中的所有元素。

     

"使用randomRIO :: Random t => (t,t) -> IO t函数(System.Random中存在的函数)来计算某个范围内的随机值。

     

"请注意,对于非空列表,选择用于根的元素是唯一的,应该改变的是用于构建子树的元素。"

2 个答案:

答案 0 :(得分:1)

我假设应从所有可能性中随机均匀地选择堆。让我们研究n节点的最小可能最小 - 最大堆数f(n+1) = sum_{k=0}^{n}{(n over k) * f(k) * f(n-k)}; f(0) = 0。唯一确定的节点位于根节点,此处没有选择。我们选择剩余节点的一个子集在左侧,然后对两个孩子重复此操作。 bash。前几个术语是1,1,2,6,24和120,这表明阶乘序列(以及序列相等的证明是孩子的游戏),它也描述了我们输入列表的可能顺序的数量。因此,我们希望每个列表顺序对应于最小 - 最大堆。

仔细考虑了几分钟后,现在看来显而易见的是,在对列表进行洗牌后,我们可以将其拆分为最小元素,选择最小左侧列表中的部分作为上述子集,然后将每一半拆分在最大元素处,然后将每个季度分成最小元素,依此类推。不同的列表顺序产生不同的堆,因此这种有限的对应关系是一对一的。

答案 1 :(得分:0)

你可能对堆的定义感到困惑。

您必须选择根作为参数的max / min元素,具体取决于堆的类型。比使用randomRIO选择哪个元素进入每个节点。