Scheme 将树表示为列表

Scheme 将树表示为列表,scheme,racket,Scheme,Racket,我应该写一个函数来计算给定树的叶子数量。在编写算法之前,我想确定我的表示 对于此树,我的表示为: (define liste (list '5 (list '1 (list '8) (list '2 (list '1) (list '9))) (list '10) (list '4 (list '9)))) 对吗 我的另一个问题是,对于这个函数,除了list之外,我是否需要任何参数 顺便说一句,我知道我不需要每次都写list,但这对我来说更清楚 编辑: (define (

我应该写一个函数来计算给定树的叶子数量。在编写算法之前,我想确定我的表示

对于此树,我的表示为:

(define liste 
    (list '5 (list '1 (list '8) (list '2 (list '1) (list '9))) (list '10) 
    (list '4 (list '9))))
对吗

我的另一个问题是,对于这个函数,除了list之外,我是否需要任何参数

顺便说一句,我知道我不需要每次都写
list
,但这对我来说更清楚

编辑:

(define (howmany L)
    (if (empty? L) 
        0
        (if (= (length L) 1)
            (+ 1 (howmany (cdr L)))
            (if (= (length (car (cdr L))) 1)
                (+ 1 (howmany (cdr L)))
                (howmany (cdr L))))))
当我调用
(howmount(list ref liste 1))
时,它返回2。但是,它应该返回3。(8,1,9)

当我调用
(howmount(list ref liste 2))
时,它返回1。好的

当我调用
(howmount(list ref liste 3))
时,它返回2。它应该返回1。(只有9个)


我的错误是什么?

缩进表达式以模拟树的图形表示,表明您的表达式是正确的:

(define liste 
  (list 5 
        (list 1 
              (list 8) 
              (list 2 
                    (list 1) 
                    (list 9)))
        (list 10) 
        (list 4 
              (list 9))))
获得结构等效值的较短方法是:

      '(5
        (1
         (8)
         (2
          (1)
          (9)))
        (10)
        (4
         (9)))
您的
叶数之和
函数不需要更多参数,但如果您想使用累加器,可以编写:

(define (sum tree)
  (sum-it tree 0))

(define (sum-it tree sum-so-far)
   ...)

数一数你的叶子

(define (node-count-of-leaves node)
  (let ((count 0))
    (node-walk (lambda (node)
                 (when (node-is-leaf? node)
                   (set! count (+ 1 count)))
               node)
    count))
关于你的
函数有多少个
函数,你没有在树上正确递归,可能在非叶子上加1

对于上述代码,抽象是您的朋友:

(define (make-node value . children)
  `(,value ,@children))

(define node-value car)
(define node-children cdr)

(define (make-leaf-node value)
   (make-node value))
(define (node-is-leaf? node)
  (null? (node-children node)))

(define (node-degree node)
  (length (node-children node)))
现在您可以使用描述性命名的函数,如
节点子节点
,而不是在表示中使用
car
cdr
cadr
等的组合

有了以上内容,就可以开始建一棵树了

(define my-tree
  (make-node 5
    (make-node 1 ...)
    (make-leaf-node 10)
    (make-node 4 ...)))
然后你可以在树上散步:

(define (node-walk func node)
  (func node)
  (for-each (lambda (node) (node-walk func node))
            (node-children node))))

下面是我对
计数树叶
函数的实现:

(define (count-leaves tree)
  (if (null? (cdr tree))
      1
      (let loop ((count 0)
                 (children (cdr tree)))
        (if (null? children)
            count
            (loop (+ count (count-leaves (car children)))
                  (cdr children))))))
或者,如果允许您在作业中使用
map
,则可以短得多:

(define (count-leaves tree)
  (if (null? (cdr tree))
      1
      (apply + (map count-leaves (cdr tree)))))
测试(在球拍下测试):


我觉得不错。顺便说一下,数字是自我评估的,不需要引用。谢谢你的建议。我编辑了我的帖子,有一些计数问题。希望你能提供帮助。也许你能从以下方面得到启发:谢谢你的建议@GoZoner,但我认为我不能使用你的方法,因为这是一项作业,如果我使用你的方法,我相信我的教授会像我作弊一样评论。一定是比为每个使用
遍历树更好的方法,这会导致你产生副作用<代码>累积树
来自SICP,这类似于折叠,但可能是树。
> (count-leaves tree)
5
> (count-leaves (second tree))
3
> (count-leaves (third tree))
1
> (count-leaves (fourth tree))
1