二叉树的映射函数的定义是:
(define (binary-tree-map proc tree)
(cond ((null? tree) null)
((not (pair? tree)) (proc tree))
(else (cons (binary-tree-map proc (car tree))
(binary-tree-map proc (cdr tree))))))
n-ary树的地图功能是什么样的? 尝试:
(define (n-tree-map proc tree)
(cond ((null? tree) null)
((not (pair? tree)) (proc tree))
(else (apply map append (lambda (p)(n-tree-map proc (cdr tree)))))))
答案 0 :(得分:6)
使用cons
(称为树结构)创建的每个n-ary树都将具有等效的镜像二叉树。树上的映射使结构保持完整,因此cons
所有binary-tree-map
处于完全相同的关系中,因此将(1 2 (3 4))
运行在n-ary树上的结果就像它是一个n-ary映射一样应该产生同样的结果。
/|\
1 2 |\
3 4
可以解释为:
/\
1 /\
2 /\
/\ nil
3 /\
4 nil
但作为二叉树,它将是:
(binary-tree-map (lambda (x) (+ x 1)) '(1 2 (3 4)))
; ==> (2 3 (4 5))
让我们试试吧!
#!r6rs
(import (rnrs))
(define-record-type (tree make-tree tree?)
(fields
(immutable children tree-children)))
(define (tree-map proc tr)
(cond ((not (tree? tr)) (proc tr))
(else (make-tree (map (lambda (x) (tree-map proc x)) (tree-children tr))))))
(define test-tree
(make-tree (list '(1 2 3)
'(2 3 4)
'(3 4 5)
(make-tree '((7 8 9)
(10 11 22))))))
(tree-map cdr test-tree)
; ==> (#tree (list '(2 3) '(3 4) '(4 5) (#tree '((8 9) (11 22)))))
现在,如果您以不同方式创建树。例如。如果一个节点不是一对,或者你需要跟踪深度,那么你需要一个不同的程序。
(define tree-tag (vector 'tree))
(define (tree? tr) (and (pair? tr) (eq? tree-tag (car tr))))
(define (make-tree children) (cons tree-tag children))
(define tree-children cdr)
(tree-map cdr test-tree)
; ==> '(#(tree) (2 3) (3 4) (4 5) (#(tree) (8 9) (11 22)))
注意列表现在可以是叶子,因为列表不代表节点。通过使用标记来标识节点,也可以使用列表结构执行此操作:
{{1}}
答案 1 :(得分:1)
简短的回答,该功能可以很好地用于n-ary树。鉴于您直接使用语言原语而不是ADT(抽象数据类型)。表示n-ary树的一种方式就是这样......
(define (make-n-ary-tree node . children)
(cons node children))
此实现中唯一与您的函数结合的奇怪之处在于它会在子树的末尾添加一个额外的空树。
在处理树或其他复杂数据类型时,理想的是构建ADT,或者在表达中表达表示的含义。
请记住,计算机 不会给您的数据带来任何影响 。程序员必须非常小心地保持一致的含义和语义。