前序和后序函数是树结构上的简单递归函数;请注意,我们小心避免树结构中出现空值:
(定义(预订单t)
(如果(null?t)
(列表)
(附加(列表(汽车))
(如果(配对?(cdr t))
(预订单(cadr t))
(列表)
(如果(和(配对?(cdr t))
(配对?(cddr t))
(预订单(caddr t))
(列表))
(定义(订单后t)
(如果(null?t)
(列表)
(追加(if(配对?(cdr t))
(后期订单(cadr t))
(列表)
(如果(和(配对?(cdrt))
(配对?(cddr t))
(后序(caddr t))
(列表)
(列表(汽车t)))
以下是应用于上一页所示示例树的函数:
>(定义t'(8(3(1)(6(4)(7)))(10()(14(13)())))
>(预订单t)
(8 3 1 6 4 7 10 14 13)
>(订单后t)
(1 4 7 6 3 13 14 10 8)
重建树是遍历树的相反操作。预购序列最左边的元素是树的根。小于根的节点位于树的左侧子级,大于根的节点则位于树的右侧子级,因此该解决方案使预排序序列中的第一个节点成为树的根,并在序列的较小部分和较大部分递归调用自身。基于后序序列重建树则相反,树的根位于列表的最后一个元素:
(定义(预构建xs)
(cond((null?xs)(列表))
((null?(cdr xs))(list(car xs))
(else(带值的调用
(λ()
(分时
(λ(x)(<x(汽车x)))(cdr x))
(λ(lo-hi)
(列表(汽车xs)(预制lo)(预制hi)))
(定义(构建后xs)
(cond((null?xs)(列表))
((空?(cdr-xs))(列表(汽车xs)
(else(带值的调用
(λ()
(分时
(λ(x)(<x(最后一个xs)))
(λ(lo-hi)
(列表(最后一个xs)(构建后lo)(构建之后hi))))
我们使用便利功能最后的
和but-last公司
:
(定义(最后一个xs)(汽车(反向xs))
(define(but-last xs)(反向(cdr(反向xs)))
以下是更多示例:
>(预构建(预订单t))
(8 (3 (1) (6 (4) (7))) (10 () (14 (13) ())))
>(后生成(后排序t))
(8 (3 (1) (6 (4) (7))) (10 () (14 (13) ())))
我们使用分裂时期
来自标准前奏曲。您可以在运行程序http://programmingpraxis.codepad.org/s86rBxGF.
页:1 2