想象一个算术表达式,例如(+ 1(* 2( - 3 5)))被认为是一个树状结构,叶子上有数字,内部节点有操作符号,如下所示:
+
/ \
1 *
/ \
2 -
/ \
3 5
我已经定义了这些函数来访问树的某些部分:
;; returns tree node
(define (operator lst)
(cadr lst))
;; returns left tree
(define (left-op lst)
(car lst))
;; returns right tree
(define (right-op lst)
(cddr lst))
我正在尝试编写3个函数preorder
,inorder
和postorder
,它们返回按遇到的顺序遍历的树的列表
我知道树遍历是如何从以前的java编程中运行的,但是我在编写这个
时遇到了麻烦前面的上述:
(preorder '(+ 1 (* 2 (- 3 5))))
=> (+ 1 * 2 - 3 5)
答案 0 :(得分:2)
您对树的实现不太正确,您需要将一个叶子(示例中的数字)表示为具有零左右子树的另一个树。此外,它有一个make-tree
“构造函数”是有用的。让我们一步一步 - 首先,正确的表示树的抽象:
(define (make-tree value left right)
(list left value right))
(define (operator tree)
(cadr tree))
(define (left-op tree)
(car tree))
(define (right-op tree)
(caddr tree))
现在进行遍历。我将帮助您完成第一个preorder
:
(define (preorder tree)
(if (null? tree)
'()
(append (list (operator tree))
(preorder (left-op tree))
(preorder (right-op tree)))))
问题中的树看起来像这样:
(define tree
(make-tree '+
(make-tree 1 '() '())
(make-tree '*
(make-tree 2 '() '())
(make-tree '-
(make-tree 3 '() '())
(make-tree 5 '() '())))))
像这样使用:
(preorder tree)
> '(+ 1 * 2 - 3 5)
其他两个遍历非常相似,只是按照每个案例的正确顺序重新排列append
的三个参数 - 我会将其作为读者的练习。