Recursion 在Scheme中插入二叉树

Recursion 在Scheme中插入二叉树,recursion,scheme,binary-tree,Recursion,Scheme,Binary Tree,我想知道如何将列表中的元素插入到二叉搜索树中。我想知道为什么下面的代码不能像我预期的那样工作。输出是((415136)()我的下一个问题是对列表中的元素进行排序,但现在我只想插入它们 我的输出对我所说的问题正确吗?我的代码如下: ( define ( make-tree value left right ) ( list value left right )) ( define ( value tree ) ( car tree )) ( define ( left tree ) ( cadr

我想知道如何将列表中的元素插入到二叉搜索树中。我想知道为什么下面的代码不能像我预期的那样工作。输出是((415136)()我的下一个问题是对列表中的元素进行排序,但现在我只想插入它们

我的输出对我所说的问题正确吗?我的代码如下:

( 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))))))
(定义(使树值左右)
(列表值左-右))
(定义(价值树)(汽车树))
(定义(左树)(cadr树))
(定义(右树)(caddr树))
(定义(插入列表L T)
(cond((null?T)(生成树L’()))
((=(轿厢L)(值T))T)
(<(汽车L)(价值T))(造树(价值T)
(插入列表(L车)(左T车))
(右)(T)
((>(汽车L)(价值T))(造树(价值T)
(左T)
(插入列表(左车)(右T(()())))
此代码的问题

编写递归代码时,考虑函数应该作为参数,以及它应该返回什么,以及基本情况是什么,通常是一个好主意。p>

(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) '())
进入

这是一个左联想折叠。让我们使用
foldl的这个定义:

(define (foldl fn init list)
  (if (null? list)
      init
      (foldl fn (fn init (car list)) (cdr list))))
在这种特殊情况下,您需要实现普通的
树插入
函数,该函数接受一棵树,元素a返回一棵新树,然后插入列表中所有元素的函数只需

(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 () ()) ())))

这个函数怎么叫?您显示了一些输出,但输入是什么?现在还不清楚你想做什么。由于您正在将
(car L)
T
的值进行比较,因此您似乎试图将
L
的第一个元素插入
T
,但随后将使用
(car L)
而不是
L
进行递归调用。你想干什么?
(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 () ()) ())))