Haskell 通过惰性计算来实现广度优先编号 Breadth-first Numbering

The code that follows sets up the defining system of equations:

  • Streams (infinite lists) of labels are used as a mediating data structure to allow equations to be set up between adjacent nodes within levels and between the last node at one level and the first node at the next. 标签流(即:无限列表)用作中间数据结构,以允许在层级内的相邻节点之间以及一个层级的最后一个节点与下一个层级的第一个节点之间建立方程式。

  • Idea: the tree numbering function for a subtree takes a stream of labels for the first node at each level, and returns a stream of labels for the node after the last node at each level. 想法:子树的编号函数接收的标签流给每层的第一个节点,并返回每层的最后一个节点之后的节点的标签流。

  • As there manifestly are no cyclic dependences among the equations, we can entrust the details of solving them to the lazy evaluation machinery in the safe knowledge that a solution will be found. 由于方程之间显然没有循环依赖关系,因此在可以找到解决方案的安全认知下,我们可以将求解它们的细节委托给惰性计算机制。

1、定义广度优先编号函数bfn
bfn :: Tree a -> Tree Integer 
bfn t = t’ 
	where 
		(ns, t’) = bfnAux (1 : ns) t

2、定义广度优先编号辅助函数bfnAux
bfnAux :: [Integer] -> Tree a -> ([Integer], Tree Integer)
bfnAux ns Empty = (ns, Empty) 
bfnAux (n:ns) (Node tl _ tr)=((n+1):ns’’, Node tl’ n tr’)
where
	(ns’, tl’) = bfnAux ns tl 
	(ns’’, tr’) = bfnAux ns’ tr
3、递归图解
  • 对于每个节点的编号:
    在这里插入图片描述

  • 对于整棵树的编号:
    在这里插入图片描述

4、编号过程
  • ①定义一个用来装树的每个节点编号(label)的无穷列表ns,即[1,2,3…].
  • ②将这个列表ns以及需要编号的树t作为参数,通过编号辅助函数bfnAux来完成编号,bfnAux返回一个二元组,这个二元组里装有无穷列表ns经过编号操作之后的得到的列表ns’’(ns在经过给左子树编号后得到ns’,ns’再给右子树编号后得到ns’’)以及编号之后的树t’.
  • ③对每个节点的编号:首先把ns的第一个元素n取出,将节点编号为元素n的值。

e.g. 以下图为例:
在这里插入图片描述

遍历根节点(n=1)及其左右子树:在给根节点编号时,bfnAux将ns [1,2,3,4,5...]写为1:[2,3,4,5..],取出第一个元素1编号给根节点,剩下的列表[2,3,4,5...]写为2:[3,4,5..],取出第一个元素2编号给根节点的左子树的根节点,剩下的列表记为ns' [3,4,5..],写为3:[4,5..],取出第一个元素3编号给根节点的右子树的根节点,剩下的列表记为ns'' [4,5..],此时bfnAux返回一个二元组,这个二元组的中新的列表ns为(n+1):ns'',即新列表ns为 [2,4,5..]

遍历第二个根节点(n=2)及其左右子树:在对第一层编号完成之后,bfnAux把编号为2的左子树作为新的根节点进行编号,将新的列表ns [2,4,5]写为2:[4,5],取出第一个元素2对已经编过号且编号为2的根节点再次编号为2,剩下的列表[4,5..]写为4:[5..],取出第一个元素4编号给左子树,剩下ns' [5..],取出5编号给右子树,剩下ns'' [6..]... 返回新的列表ns [3,6..]

以此类推...
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值