Tree Don';I don’我不明白这个方案对于制作平衡二叉树的作用

Tree Don';I don’我不明白这个方案对于制作平衡二叉树的作用,tree,scheme,Tree,Scheme,我无法理解这些功能: (define (list->tree elements) (car (partial-tree elements (length elements)))) (define (partial-tree elts n) (if (= n 0) (cons '() elts) (let ((left-size (quotient (- n 1) 2))) (let ((left-result (partial-tree elts le

我无法理解这些功能:

(define (list->tree elements)
  (car (partial-tree elements (length elements))))

(define (partial-tree elts n)
  (if (= n 0)
    (cons '() elts)
    (let ((left-size (quotient (- n 1) 2)))
      (let ((left-result (partial-tree elts left-size)))
        (let ((left-tree (car left-result))
            (non-left-elts (cdr left-result))
            (right-size (- n (+ left-size 1))))
        (let ((this-entry (car non-left-elts))
              (right-result (partial-tree (cdr non-left-elts)
                                          right-size)))
          (let ((right-tree (car right-result))
                (remaining-elts (cdr right-result)))
            (cons (make-tree this-entry left-tree right-tree)
                  remaining-elts))))))))
我猜
部分树
将整个列表分成一半,并递归地为每一半生成子树。但是我对所有的
汽车
/
cdr
完全迷路了。具体而言:

  • 为什么在
    (car(部分树元素(长度元素))
    中需要
    car

  • 为什么
    中的
    左结果
    (让((左结果(部分树elts左大小))
    取整个列表
    elts

  • 在此情况下,
    剩余的ELT
    是什么:

    (cons (make-tree this-entry left-tree right-tree)
          remaining-elts))))
    
  • 我试图使用一个测试用例
    ”(13 5 7 9)
    ,但是当我看到递归调用
    (部分树elts left size)
    ,我完全困惑了,不知道
    左结果
    左树
    右结果
    会是什么


    如果你想知道递归是如何工作的,那么最好写下所有的步骤(用少量的输入)。假设我们有
    (1 3 5 7 9)
    作为
    列表->树的输入。然后
    部分树将执行以下步骤:

    ;; > (partial-tree '(1 3 5 7 9) 5)
    ;;   left-size : 2
    ;;   >> *1 (partial-tree '(1 3 5 7 9) 2)
    ;;     left-size : 0
    ;;     >>> *1 (partial-tree '(1 3 5 7 9) 0)
    ;;       >>>> n == 0
    ;;       <<<< '(() . (1 3 5 7 9))
    ;;     left-result   : '(() . (1 3 5 7 9))
    ;;     left-tree     : '()
    ;;     non-left-elts : '(1 3 5 7 9)
    ;;     this-entry    : 1
    ;;     right-size    : 1
    ;;     >>> *2 (partial-tree '(3 5 7 9) 1)
    ;;       left-size : 0
    ;;       >>>> *1 (partial-tree '(3 5 7 9) 0)
    ;;         >>>>> n == 0
    ;;         <<<<< '(() . (3 5 7 9))
    ;;       left-result   : '(() . (3 5 7 9))
    ;;       left-tree     : '()
    ;;       non-left-elts : '(3 5 7 9)
    ;;       this-entry    : 3
    ;;       right-size    : 0
    ;;       >>>> *2 (partial-tree '(5 7 9) 0)
    ;;         >>>>> n == 0
    ;;         <<<<< '(() . (5 7 9))
    ;;       right-tree     : '()
    ;;       remaining-elts : '(5 7 9)
    ;;       <<<< *3 '(#(() 3 ()) . (5 7 9))
    ;;     right-result : '(#(() 3 ()) . (5 7 9))
    ;;     right-tree   : '#(() 3 ())
    ;;     remaining-elts : '(5 7 9)
    ;;     <<< '(#(() 1 #(() 3 ())) . (5 7 9))
    ;;   left-result   : '(#(() 1 #(() 3 ())) . (5 7 9))
    ;;   left-tree     : #(() 1 #(() 3 ()))
    ;;   non-left-elts : '(5 7 9)
    ;;   this-entry    : 5
    ;;   >> *2 (partial-tree '(7 9) 2)
    ;;     left-size : 0
    ;;     >>> *1 (partial-tree '(7 9) 0)
    ;;       >>>> n == 0
    ;;       <<<< '(() . (7 9))
    ;;     left-result   : '(() . (7 9))
    ;;     left-tree     : '()
    ;;     non-left-elts : '(7 9)
    ;;     this-entry    : 7
    ;;     right-size    : 1
    ;;     >>> *2 (partial-tree '(9) 1)
    ;;       left-size : 0
    ;;       >>>> *1 (partial-tree '(9))
    ;;         >>>>> n == 0
    ;;         <<<<< '(() . (9))
    ;;       left-result   : '(() . (9))
    ;;       left-tree     : '()
    ;;       non-left-elts : '()
    ;;       this-entry    : 9
    ;;       right-size    : 0
    ;;       >>>> *2 (partial-tree '() 0)
    ;;         >>>>> n == 0
    ;;         <<<<< '(() . ())
    ;;       right-result   : '(() . ())
    ;;       right-tree     : '()
    ;;       remaining-elts : '()
    ;;       <<<< *3 '(#(() 9 ()) . ())
    ;;     right-result   : '(#(() 9 ()) . ())
    ;;     right-tree     : '#(() 9 ())
    ;;     remaining-elts : '()
    ;;     <<< *3 '(#(() 7 #(() 9 ())) . ())
    ;;   right-result   : '(#(() 7 #(() 9 ())) . ())
    ;;   right-tree     : 
    ;;   remaining-elts : '()
    ;;   << *3 '(#(() 1 #(() 3 ())) 5 #(() 7 #(() 9 ())) . ())
    ;; < '(#(() 1 #(() 3 ())) 5 #(() 7 #(() 9 ())) . ())
    
    ;;>(部分树’(1 3 5 7 9)5)
    左尺寸:2
    ;>>*1(部分树’(1 3 5 7 9)2)
    ;左尺寸:0
    ;;;>>>*1(部分树’(1 3 5 7 9)0)
    ;;>>>>n==0
    *2(部分树’(3 5 7 9)1)
    ;左尺寸:0
    ;;;>>>>*1(部分树’(3 5 7 9)0)
    ;;>>>>>n==0
    *2(部分树’(579)0)
    ;;>>>>>n==0
    ;;>>>n==0
    *2(部分树’(9)1)
    ;左尺寸:0
    ;;>>>>*1(部分树(9))
    ;;>>>>>n==0
    ;;*2(部分树“()0)
    ;;>>>>>n==0
    ;ad1)

    (部分树elts n)
    返回一对两个值:第一个值是包含
    elts
    的第一个
    n
    元素的树,第二个值是
    elts
    的剩余元素的列表(可以包含比
    n
    更多的元素)

    广告2) 大小
    left size
    确定列表中使用了多少元素。 没有必要先修剪列表

    Ad 3)elts中的n+1、n+2等元素。即未用于生成树的元素

    #lang racket
    (define (list->tree elements)
      (car (partial-tree elements (length elements))))
    
    (define (make-tree this left-tree right-tree)
      (match (list left-tree this right-tree)
        [(list '() x '()) (list   x)]
        [(list '() x r)   (list   x r)]
        [(list  l  x '()) (list l x)]
        [(list  l  x r)   (list l x r)]))
    
    (define (partial-tree elts n)
      (if (= n 0)
          (cons '() elts)
          (let* ([left-size      (quotient (- n 1) 2)]
                 [left-result    (partial-tree elts left-size)]
                 ; left result is now a pair of
                 [left-tree      (car left-result)]     ; a tree with (n-1)/2 elementer
                 [non-left-elts  (cdr left-result)]     ; a list of elements not in left-tree
    
                 [this-entry     (car non-left-elts)]   ; the (n-1)/2+1'th element
    
                 [right-size     (- n left-size 1)]     ; n - left-size - 1
    
                 ; note: left-size + 1 + right-size  = n
    
                 [right-result   (partial-tree (cdr non-left-elts) right-size)]
                 [right-tree     (car right-result)]    ; a tree with n - left-size - 1 elements
                 [remaining-elts (cdr right-result)])   ; element n+1, n+2, ... of elts
            (cons (make-tree this-entry left-tree right-tree) ; a tree with n elements
                  remaining-elts))))                          ; element n+1, n+2, ... of elts
    
    (partial-tree '(a b c d e f g h) 1)
    (partial-tree '(a b c d e f g h) 2)
    (partial-tree '(a b c d e f g h) 3)
    (partial-tree '(a b c d e f g h) 4)
    (partial-tree '(a b c d e f g h) 5)
    (partial-tree '(a b c d e f g h) 6)
    (partial-tree '(a b c d e f g h) 7)
    (partial-tree '(a b c d e f g h) 8)
    
    输出:

    '((a) b c d e f g h)
    '((a (b)) c d e f g h)
    '(((a) b (c)) d e f g h)
    '(((a) b (c (d))) e f g h)
    '(((a (b)) c (d (e))) f g h)
    '(((a (b)) c ((d) e (f))) g h)
    '((((a) b (c)) d ((e) f (g))) h)
    '((((a) b (c)) d ((e) f (g (h)))))