从树中查找最大值

时间:2016-11-10 20:58:08

标签: functional-programming scheme lisp racket typed-racket

我试图找到给定树的最大数量:

(define-struct (Some T)
  ([value : T]))

(define-type (Option T)
  (U 'None (Some T)))

(define-type BST (U 'E Nd))

(define-struct Nd
  ([root : Integer]
   [lsub : BST]
   [rsub : BST]))

(: maxi : BST Integer -> Integer)
(define (maxi x acc)
  (match x
        ('E acc)
((Nd ro ls rs)
    (cond
      ((> ro acc) (maxi ls ro))
      (else
       (maxi rs acc))))))

当我输入以下内容时,上述报价无效:

(maxi(Nd 1)(Nd 2(Nd 4(Nd 8' E' E)(Nd 9' E' E))(Nd 5' E(E)E))(Nd 3(Nd 6' E' E)(Nd 7' E' E)))0)

有人可以帮忙吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

所以这是你的测试:

(maxi
   (Nd
      1
      (Nd 2
         (Nd 4
            (Nd 8 'E 'E)
            (Nd 9 'E 'E))
         (Nd 5 'E 'E))
      (Nd 3
         (Nd 6 'E 'E)
         (Nd 7 'E 'E)))
   0)

以下是发生的事情:

   acc  root   what to do?
  ---------------------------------
   0    1      go left with acc = root
   1    2      idem
   2    4      idem
   4    8      idem
   8    E      return 8

如果您希望输入树满足binary search tree属性,说明左子树上的值总是大于root,而右子树的值都小或相等,那么您的测试树格式不正确BST,因为9大于4。

顺便说一下,如果你有BST,那么最大值会在哪里?

如果树只是一棵随机树,那么你必须先计算两个子树和根值的最大值才能确定整体最大值。

基本上,你想做:

(tree-max (Nd root left right)) = (max root 
                                       (tree-max left) 
                                       (tree-max right))

如果你想以递归方式进行,你将在基本情况下遇到一个问题,因为你必须为空叶节点提供一个最大值:你要选择的任何值都会使你的代码对于包含树的树不正确严格低于该值的值。假设您选择零并计算仅具有严格负数的树的最大值,则零是错误的答案,因为它不会出现在树中(您可以做什么?)。

您可以选择使用累加器而不是递归,但在这种情况下,您将需要两个累加器:到目前为止的最大值和下一个要访问的子树列表。基本上你用堆分配的堆栈替换调用堆栈。

我目前无法测试以下代码,但这是一个可能的实现:

(define tree-max (tree greatest todo)
  (match tree
    ('E greatest (if (null? todo) 
                 greatest
                 (tree-max (first rest) 
                           greatest 
                           (rest todo))
    ((Nd root left right) (tree-max left
                                    (max greatest root) 
                                    (cons right todo))))