【发布时间】:2015-02-02 09:11:51
【问题描述】:
我正在自学 SICP,很难找到递归函数的增长顺序。
以下过程 list->tree 将有序列表转换为平衡搜索树:
(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))))))))
我一直在网上查看解决方案,我认为以下网站提供了最佳解决方案,但我无法理解它:
jots-jottings.blogspot.com/2011/12/sicp-exercise-264-constructing-balanced.html
我的理解是,程序“partial-tree”每次被调用时都会重复调用三个参数——分别是“this-entry”、“left-tree”和“right-tree”。 (并且只有在必要时才使用“remaining-elts”——无论是在第一次“partial-tree”调用中还是在调用“non-left-elts”时)
- this-entry 调用:car、cdr 和 cdr(left-result)
- left-entry 调用:car、cdr 和其自身的长度每一步减半
- 右入口调用:car,本身以 cdr(cdr(left-result)) 作为参数,长度减半
'left-entry' 将以 2 log(n) 为基数,并且所有三个参数都分别调用 'left-entry'。 因此它将具有三叉树状结构,并且我认为总步数类似于 3^log(n)。但解决方案说它只使用每个索引 1..n 一次。但是'this-entry'不是将每个节点上的相同索引减少为'right-entry'吗?
我很困惑.. 此外,在 (a) 部分,解决方案网站指出:
"在非终止情况下partial-tree首先计算个数 应该进入平衡二叉树左子树的元素 大小为 n 的树,然后使用元素调用部分树,并且 既产生这样的子树的值,又产生不的元素列表 在那个子树中。然后它将未使用元素的头部作为 当前节点的值"
我相信该程序在左树之前执行此条目。为什么我错了?
这是我关于 CS 的第一本书,我还没有接触过 Master Theorem。 在一些解决方案中提到了它,但希望我应该能够在不使用它的情况下解决这个问题。
感谢您的阅读,期待您的热情回复,
克里斯
【问题讨论】:
标签: recursion tree scheme sicp