如何遍历Scheme中的n-ary树?

时间:2018-03-30 02:23:10

标签: scheme lisp racket

我一直试图让这项工作暂时(我是计划的新手)。

(define atree '(10 (2 (4 (9 (3)) (12 (1 (2))) (16))) (5 (7) (21)) (6)))

(define (children elem tree)
  (if (eqv? tree '())
      '()
      (if (number? (car tree))
          (if (eqv? elem (car tree))
              (getchilds (cdr tree))
              (children elem (cdr tree)))
          (if (eqv? elem (caar tree))
              (getchilds (cdar tree))
              (children elem (cadr tree))))))


(define (getchilds childNodes)
  (cond ((null? childNodes) '())
        (else (cons (caar childNodes)
                    (getchilds (cdr childNodes))))))

理想情况下,我应该能够归还特定父母的子女。而且我设法让它适用于数字10,2,5,6(即(children 10 tree)。但我显然做错了,因为它不会为任何孙子节点工作。< / p>

我的想法是尝试像循环一样遍历每个元素,但我不认为这是我设法完成的。它是一个可以拥有任意数量节点的n-ary树,我已经尝试了谷歌搜索并且做得很短。

有人有指导他们的方向吗?理想情况下,我只想从左到右遍历该列表的每个元素......

1 个答案:

答案 0 :(得分:0)

很明显,错误是子列表是一个节点列表,而您的过程只占用一个节点。

你应该拆分并进行抽象。现在你的程序如何做得太多,而且你不知道你是否使用car作为列表元素或节点的id:

(define (node? tree)
  ...)
(node? '(1))         ; ==> #t
(node? '(1 (2) (3))) ; ==> #t
(node? '())          ; ==> #f
(node? '1)           ; ==> #f

(define (node-id tree)
  ...)
(node-id '(1 (2))) ; ==> 1

(define (node-children tree)
  ...)
(node-children '(1 (2) (3))) ; ==> ((2) (3))

(define (node-ids list-of-nodes)
  ...)
(node-list-ids '((2) (3))) ; ==> (2 3)

(define (find-node id tree)
  ...)

现在这是你遇到问题的地方。它需要一个节点作为参数而不是节点列表。为了规避你可能想要制作一个列表的帮助者:

(define (find-node id tree)
  (let helper ((list-of-tree (list tree)))
    ...))

(find-node 1 '())          ; ==> #f 
(find-node 1 '(1 (2)))     ; ==> (1 (2)) 
(find-node 3 '(1 (2) (3))) ; ==> (3) 

或者您可以使用高级函数,例如SRFI-1 has any

(define (find-node id tree)
  (let helper ((tree tree))
    (cond (<tree-is-not-a-node> #f)
          (<tree-has-same-id> tree)
          (else (any helper <list-of-children>)))))

现在你想要某个节点的子节点的id。当你测试了抽象时,你的程序很容易实现:

(define (find-child-ids id tree)
  (let ((tree (find-node id tree)))
    (if tree
        (node-list-ids (node-children tree))
        '()))) ; non existing node has no children

(find-node 1 '())      ; ==> () 
(find-node 1 '(1 (2))) ; ==> (2) 

如果我自己这样做,我可能会使用SRFI-136 records对树进行建模。