代表树作为列表

时间:2014-05-04 16:21:23

标签: scheme racket

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

my tree

对于这棵树,我的代表是:

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

这是对的吗?

我的另一个问题是除了此功能的列表外,我还需要任何参数吗?

是的,我知道我不需要每次都写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))))))

当我致电(howmany (list-ref liste 1))时,它会返回2.但是,它应该返回3. (8,1,9)

当我拨打(howmany (list-ref liste 2))时,它会重新调整1.很好。

当我致电(howmany (list-ref liste 3))时,它会返回2.它应该返回1.(仅限9)

我的错误是什么?

3 个答案:

答案 0 :(得分:4)

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

(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)))

你的sum-of-leaves函数不需要更多参数,但是如果你想使用累加器,你可以写:

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

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

答案 1 :(得分:2)

计算你的叶子。

(define (node-count-of-leaves node)
  (let ((count 0))
    (node-walk (lambda (node)
                 (when (node-is-leaf? node)
                   (set! count (+ 1 count)))
               node)
    count))

关于你的how many函数,你没有正确地递归树,也许在非叶子上加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)))

现在您可以使用描述性命名的函数,例如node-children,而不是在您的表示中使用carcdrcadr等的组合。 / p>

有了上述内容,请继续构建一棵树。

(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))))

答案 2 :(得分:2)

这是我对count-leaves函数的实现:

(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)))))

测试(在Racket下测试):

> (count-leaves tree)
5
> (count-leaves (second tree))
3
> (count-leaves (third tree))
1
> (count-leaves (fourth tree))
1