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
中存在的函数)来计算某个范围内的随机值。"请注意,对于非空列表,选择用于根的元素是唯一的,应该改变的是用于构建子树的元素。"
答案 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选择哪个元素进入每个节点。