要遍历一棵树并累积它的所有元素,我们会遇到以下三种情况:
'()
list
函数,让它变成一个只有单个元素的列表append
过程(MIT Scheme 也内置了这个过程),对两棵子树的所有元素进行累积;;; 28-fringe.scm
(define (fringe tree)
(cond ((null? tree) ; 空树
'())
((not (pair? tree)) ; 叶子
(list tree))
(else
(append (fringe (car tree)) ; 累积左子树所有元素
(fringe (cadr tree)))))) ; 累积右子树所有元素
测试:
1 ]=> (load "28-fringe.scm")
;Loading "28-fringe.scm"... done
;Value: fringe
1 ]=> (define x (list (list 1 2) (list 3 4)))
;Value: x
1 ]=> (fringe x)
;Value 13: (1 2 3 4)
1 ]=> (fringe (list x x))
;Value 14: (1 2 3 4 1 2 3 4)
可以通过增加一些辅助函数,来让 fringe
函数的定义更具可读性:
;;; 28-better-fringe.scm
(define (fringe tree)
(cond ((empty-tree? tree)
'())
((leaf? tree)
(list tree))
(else
(append (fringe (left-branch tree))
(fringe (right-branch tree))))))
(define (empty-tree? tree)
(null? tree))
(define (leaf? tree)
(not (pair? tree)))
(define (left-branch tree)
(car tree))
(define (right-branch tree)
(cadr tree))
对 fringe
进行测试:
1 ]=> (load "28-better-fringe.scm")
;Loading "28-better-fringe.scm"... done
;Value: right-branch
1 ]=> (define x (list (list 1 2) (list 3 4)))
;Value: x
1 ]=> (fringe x)
;Value 15: (1 2 3 4)
1 ]=> (fringe (list x x))
;Value 16: (1 2 3 4 1 2 3 4)