Tree 方案中n元树的映射函数

Tree 方案中n元树的映射函数,tree,functional-programming,scheme,lisp,Tree,Functional Programming,Scheme,Lisp,二叉树映射函数的定义如下: (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元树的映射函数是什么样子的

二叉树映射函数的定义如下:

(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元树的映射函数是什么样子的? 尝试:


cons
(称为树结构)构成的每个n元树都将有一个镜像二叉树。树上的映射保持结构,因此所有的
cons
处于完全相同的关系中,因此在n元树上运行
二叉树映射
的结果应该是相同的

(12(34))
可以解释为:

 /|\
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)))

简而言之,这个函数可以很好地用于n元树。假设您直接使用语言原语而不是ADT(抽象数据类型)。表示n元树的一种方法如下

(define (make-n-ary-tree node . children)
 (cons node children)) 
这个实现与函数结合在一起的唯一奇怪之处是它会在子树的末尾添加一个额外的空树)

在处理树或其他复杂数据类型时,最好构造一个ADT,或者在注释中说明表示的含义


记住,计算机不会对你的数据的含义大惊小怪。作为程序员,您必须非常小心地保持一致的含义和语义

非常好,应用程序的版本会是什么样子?@X10D
(apply+10'(1 2 3))
(+10 1 2 3)
相同,但除非您有一个需要作为参数的列表,否则您不会使用
apply
。不太多,可能语义更多地是派生意义的方法或手段。如果说“保持数据的一致表示和语法”,会更清楚(尽管不是等效的)
(define (make-n-ary-tree node . children)
 (cons node children))