【问题标题】:make tree in scheme在计划中制作树
【发布时间】:2012-08-22 10:51:32
【问题描述】:
(define (entry tree) (car tree))
(define (left-branch tree) (cadr tree))
(define (right-branch tree) (caddr tree))
(define (make-tree entry left right) (list entry left right))

(define (mktree order items_list)
  (cond ((= (length items_list) 1)
         (make-tree (car items_list) '() '()))
        (else 
         (insert2 order (car items_list) (mktree order (cdr items_list))))))

(define (insert2 order x t)
  (cond ((null? t) (make-tree x '() '()))
      ((order x  (entry t))
       (make-tree (entry t) (insert2 order x (left-branch t)) (right-branch t)))
      ((order  (entry t) x )
       (make-tree (entry t) (left-branch t) (insert2 order x (right-branch t))))
      (else t)))

结果是:

(mktree (lambda (x y) (< x y)) (list 7 3 5 1 9 11))
(11 (9 (1 () (5 (3 () ()) (7 () ()))) ()) ())

但我想得到:

(7 (3 (1 () ()) (5 () ())) (9 () (11 () ())))

问题出在哪里?

【问题讨论】:

  • 已将您的标签更新为方案,因为我想这就是它......
  • 这是球拍吗? (以前称为 PLT 方案。)
  • 看起来你需要一些更简单的测试用例!

标签: algorithm recursion tree scheme binary-tree


【解决方案1】:

在这里,试试这个:

(define (mktree order lst)
  (let loop ((lst  lst)
             (tree '()))
    (if (null? lst)
        tree
        (loop (cdr lst) (insert order (car lst) tree)))))

(define (insert order ele tree)
  (cond ((null? tree)
         (make-tree ele '() '()))
        ((order ele (entry tree))
         (make-tree (entry tree)
                    (insert order ele (left-branch tree))
                    (right-branch tree)))
        ((order (entry tree) ele)
         (make-tree (entry tree)
                    (left-branch tree)
                    (insert order ele (right-branch tree))))
        (else tree)))

它按预期工作:

(mktree < '(7 3 5 1 9 11)) 
> '(7 (3 (1 () ()) (5 () ())) (9 () (11 () ())))

您的insert2 过程很好,但mktree 过程应该表示为对列表的迭代,累加器跟踪到目前为止插入的元素的树。这有两个效果:

  1. mktree 现在是尾递归的,并且
  2. 列表中元素的迭代顺序颠倒了

最后一个特别会解决您的问题:即使您的解决方案生成一棵二叉树,order 属性也会与您的预期相反。请注意,反转输入列表也可以。

【讨论】:

  • 奥斯卡的权利;你现在得到的树也满足你想要的二叉树不变量。但是树是通过以相反的顺序考虑输入来构建的。正如 John Clements 所建议的,您应该首先尝试小型测试用例来识别问题。为了更清楚地说明这一点,请考虑一个更小的测试输入,例如 '(2 1 3)。
【解决方案2】:

Oscar Lopez 的答案是正确的,因为你的递归性质 insert2 函数调用,它首先使 S 表达式完全展开,然后从列表的最后 2 个元素开始评估(在您的情况下为 9 和 11)... 作为这一点的证明,您可以看到,如果您以相反的顺序放入列表中,您会得到 正确结果:

(mktree (lambda (x y) (&lt; x y)) (list 11 9 1 5 3 7))

(7 (3 (1 () ()) (5 () ())) (9 () (11 () ())))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多