Итак, хороший способ сделать это - использовать сопоставление с образцом Racket. Помимо этого, также приятно использовать поиск по повестке дня, чтобы весь процесс был повторяющимся. Таким образом, функция, которая производит суммирование, будет иметь три аргумента:
- текущий узел;
- текущая повестка дня узлов, на которые она должна смотреть;
- промежуточный итог;
И затем он решает, что делать, на основе сопоставления этих аргументов с шаблоном, перебирая узлы и выталкивая и выталкивая вещи из повестки дня.
* 1012 1013 * и
empty-node
, а также образец дерева, составленный из них следующим образом:
(struct node (value left middle right))
(struct empty-node ())
(define sample-tree
(node 1
(node 2
(empty-node)
(node 3 (empty-node) (empty-node) (empty-node))
(node -1
(node 1 (empty-node) (empty-node) (empty-node))
(empty-node)
(empty-node)))
(node 10 (empty-node) (empty-node) (empty-node))
(empty-node)))
Мы можем написать функцию для суммирования дерева следующим образом:
(define (sum-node-tree node-tree)
(define/match (snt-loop thing agenda sum)
[((empty-node) '() s)
;; an empty node, nothing on the agenda: we're done
s]
[((empty-node) (cons next more) s)
;; an empty node, but there is an agenda, so start on the next agenda
;; item
(snt-loop next more s)]
[((node (? number? v) l m r) a s)
;; a node with a value: sum the value into the total, push the middle
;; and right children onto the agenda, and start on the left child.
(snt-loop l (list* m r a) (+ s v))]
[(_ _ _)
;; something bad in the tree
(error 'sum-node-tree "bogus tree")])
(snt-loop node-tree '() 0))
затем
> (sum-node-tree sample-tree)
16