Recursion SICP 2.64递归过程的增长阶
我在自学SICP,很难找到递归函数的增长顺序 以下过程列表->树将有序列表转换为平衡搜索树:Recursion SICP 2.64递归过程的增长阶,recursion,tree,scheme,sicp,Recursion,Tree,Scheme,Sicp,我在自学SICP,很难找到递归函数的增长顺序 以下过程列表->树将有序列表转换为平衡搜索树: (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)))
(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))))))))
我一直在网上查看解决方案,我认为以下网站提供了最好的解决方案,但我很难理解它:
我的理解是,过程“partial tree”每次调用时都会重复调用三个参数,分别是“this entry”、“left tree”和“right tree”。(只有在必要时才使用“剩余ELT”-无论是在第一个“部分树”调用中还是在调用“非左ELT”时)
Chris您需要了解
如何让表单工作。在
(let ((left-tree (car left-result))
(non-left-elts (cdr left-result))
左树
不调用任何东西。它被创建为一个新的词汇变量,并被赋值为(car left result)
。其周围的括号仅用于将描述由let
形式引入的一个变量的元素组合在一起:变量的名称及其值:
(let ( ( left-tree (car left-result) )
;; ^^ ^^
( non-left-elts (cdr left-result) )
;; ^^ ^^
下面是如何理解递归过程的工作原理:不要
只是不要试图去理解它是如何工作的;相反,分析它做什么,假设它做(对于较小的情况)它应该做什么
在这里,(部分树elts n)
接收两个参数:元素列表(大概放在树中)和列表长度。它返回
树的cons对-转换的结果,以及最顶端调用中的剩余元素(如果length参数正确的话),这些元素应该没有剩余
现在我们知道了它应该做什么,我们看看里面。事实上,假设上面所说的是完全有意义的:将元素数量减半,处理列表,将树和剩余列表取回(现在为非空),然后处理剩下的内容
此条目
不是树-它是树节点中的元素:
(let ((this-entry (car non-left-elts))
背景
(right-size (- n (+ left-size 1))
意味着n==右尺寸+1+左尺寸
。这是进入节点本身的1个元素,this entry
元素
由于每个元素直接进入其节点一次,该算法的总运行时间与输入列表中的元素数成线性关系,使用对数堆栈空间。您的解决方案和第64页的let表达式定义的重新阅读清楚了这一点。我很高兴看到你的回答,谢谢。(如果我以前没有说过这句话,)不客气
(right-size (- n (+ left-size 1))