我想知道如何将列表中的元素插入到二叉搜索树中。我想知道为什么下面的代码不能像我预期的那样工作。输出是'((4 1 5 13 6)()())我的下一个问题是要对列表中的元素进行排序,但是现在我只想插入它们。
我说的输出是否正确?我的代码如下:
( define ( make-tree value left right )
( list value left right ))
( define ( value tree ) ( car tree ))
( define ( left tree ) ( cadr tree ))
( define ( right tree ) ( caddr tree ))
(define (insert-list L T)
(cond ((null? T) (make-tree L '() '()))
((= (car L) (value T)) T)
((< (car L) (value T)) (make-tree (value T)
(insert-list (car L) (left T))
(right T)))
((> (car L) (value T)) (make-tree (value T)
(left T)
(insert-list (car L) (right T))))))
答案 0 :(得分:2)
在编写递归代码时,通常最好考虑函数应该作为参数使用什么,它应该返回什么,以及基本情况是什么。
(define (insert-list L T)
(cond
((null? T) (make-tree L '() '())) ; case 1
((= (car L) (value T)) T) ; case 2
((< (car L) (value T)) (make-tree (value T) ; case 3
(insert-list (car L) (left T))
(right T)))
((> (car L) (value T)) (make-tree (value T) ; case 4
(left T)
(insert-list (car L) (right T))))))
根据您的描述,insert-list
应该采用元素和树的列表,并返回您从一个接一个地插入这些元素到树中的树。这段代码实际上是这样做的吗?有几种情况:
((4 1 5 13 6) () ())
这样的结果的原因。你得到了这个基本案例并返回了(make-tree L '() '()))
。(insert-list '(2 3 4) '(2 () ()))
之类的测试用例,则会看到返回值为(2 () ())
。(insert-list (car L) (left T))
,但这没有意义,因为insert-list
的第一个参数应该是一个元素列表,并且您使用(car L)
来调用它,这是一个单独的元素。但是,你认识到(car L)
需要插入到树的左子树中,而你正在构建它,如果只是你正在调用(insert-element (car L) (left T))
,那么你是对的。但是,之后您仍然没有对元素的 rest 做任何事情。如果您正在尝试获取数字列表并将第一个插入树中以获取新树,则将第二个数字插入该树中,依此类推,即可重新寻找像这样的伪代码:
tree = initial-tree
for element in list
tree = insert(element,tree)
return tree
这种操作通常由fold
在功能上表示。我在Flattening a List of Lists的答案中详细描述了折叠,并且有很多关于它们的信息。想法是你想要转变
(insert-list '(4 1 5 13 6) '())
进入
(tree-insert (tree-insert (tree-insert (tree-insert (tree-insert '() 4) 1) 5) 13) 6)
这是左关联折叠。我们使用foldl
:
(define (foldl fn init list)
(if (null? list)
init
(foldl fn (fn init (car list)) (cdr list))))
在这种特殊情况下,你需要实现你的普通tree-insert
函数,它接受一个树,一个元素返回一个新树,然后你的函数插入 all 列表中的元素只是
(lambda (tree elements)
(foldl tree-insert tree elements))
例如,
> (foldl tree-insert '() '(3 5 8 1 9))
(3 (1 () ()) (5 () (8 () (9 () ()))))
> (foldl tree-insert '() '(5 8 2 3 1 6 9))
(5 (2 (1 () ()) (3 () ())) (8 (6 () ()) (9 () ())))
> (foldl tree-insert '() '(4 1 5 13 6)) ; the test from the question
(4 (1 () ()) (5 () (13 (6 () ()) ())))