我想创建一个函数inbetweenbst: int int BST -> ilist
,用作(inbetweenbst i j t),它生成一个严格在i和j之间的消费BST中所有键的列表。如果t中没有任何带有此范围内键的元素,则该函数应生成一个空列表。假设i≤j
此外,我必须确保运行时间必须为O(n),其中n是t中元素的数量,而不是使用变异。
我提出了以下代码,它基本上将树更改为只有正确的节点:
(define (bst->list t)
(cond
[(empty? t) empty]
[else
(append (bst->list (BST-left t)) (cons (BST-key t) empty) (bst->list (BST-right t)))]))
(define (list->bst lst)
(cond
[(empty? lst) empty]
[else (make-BST (first lst) empty (list->bst (rest lst)))]))
(define (inbetweenbst i j t)
(define bst (list->bst (bst->list t)))
(cond
[(empty? bst) empty]
[(and (> (BST-key bst) i) (< (BST-key bst) j))
(cons (BST-key bst) (inbetweenbst i j (BST-right bst)))]
[else (inbetweenbst i j (BST-right bst))]))
但我认为我的代码在O(n ^ 2)中运行....任何让它运行O(n)的建议......我很漂亮我不能使用append
因为它是O(n)函数,我只限于cons
...我在想法上迷失了,任何建议都有帮助吗? = d
答案 0 :(得分:2)
我相信程序bst->list
可以用这样简单有效的方式编写:
(define (bst->list t)
(let inorder ((tree t)
(acc empty))
(if (empty? tree)
acc
(inorder (BST-left tree)
(cons (BST-key tree)
(inorder (BST-right tree)
acc))))))
在上面的代码中,我没有使用append
来构建所有键的列表,只有cons
个操作。之后,构建一个过滤所需范围内的键的过程应该是微不足道的:
(define (in-between-bst i j t)
(filter <???>
(bst->list t)))
编辑:
以下是bst->list
程序,未使用let
并使用cond
代替if
:
(define (bst->list t)
(inorder t empty))
(define (inorder tree acc)
(cond ((empty? tree)
acc)
(else
(inorder (BST-left tree)
(cons (BST-key tree)
(inorder (BST-right tree)
acc))))))
答案 1 :(得分:1)
首先考虑通过有序遍历将树转换为列表的递归方法。将递归调用的结果附加到树的左子节点,然后是当前节点,然后是对树的右子节点的递归调用的结果;到达空节点时递归停止。
现在将其转换为仅在所需范围内的节点上运行的方法。唯一的区别是,当您到达空节点时,或者当您到达超出所需范围的节点时,递归会停止。
在您的代码中,您已经拥有了第一个函数,名为bst-&gt; list。您所要做的就是修改函数以添加另一个cond子句(在空?之后和else之前),以便在超出所需范围时返回空树。不需要变量bst,这只是t。
答案 2 :(得分:0)
作为消除append
调用的提示,考虑一个更简单的函数,它只是将S表达式展平为原子列表。这是天真的版本:
;; flatten : S-expr -> (listof atom)
(define (flatten x)
(cond [(null? x)
null]
[(pair? x)
(append (flatten (car x))
(flatten (cdr x)))]
[else
(list x)]))
这是另一个版本。它不使用重复和附加,而是使用一个辅助函数,该函数接受一个额外的参数,该参数包含当前参数右侧所有内容的展平列表。
;; flatten : S-expr -> (listof atom)
(define (flatten x)
(flatten* x null))
;; flatten* : S-expr (listof atom) -> (listof atom)
(define (flatten* x onto)
(cond [(null? x)
onto]
[(pair? x)
(flatten* (car x)
(flatten* (cdr x) onto))]
[else
(cons x onto)]))
您可以将此技术应用于您的问题。