Recursion 删除方案中的节点

Recursion 删除方案中的节点,recursion,scheme,binary-tree,nodes,Recursion,Scheme,Binary Tree,Nodes,我试图在scheme中从二元搜索树中删除一个节点,但在删除部分代码时遇到问题。如何在不在scheme中创建新树的情况下删除节点值 (define (delete-node v T) (cond ((null? T) '()) ((< v (value T)) (delete-node v (left T))) ((> v (value T)) (delete-node v (right T))) (else (cond ((

我试图在scheme中从二元搜索树中删除一个节点,但在删除部分代码时遇到问题。如何在不在scheme中创建新树的情况下删除节点值

(define (delete-node v T)
  (cond ((null? T) '())
    ((< v (value T))
     (delete-node v (left T)))
    ((> v (value T))
     (delete-node v (right T)))
    (else
      (cond ((and (null? (right T))(not (null? (left T)))) '())
             ;promote the (left T) to the node
             ;repeat 
            ((and (null? (left T))(not (null? (right T)))) '())
             ;promote the (right T) to the node                                           
             ;repeat
(定义(删除节点v T)
(cond((null?T)“”())
(v(值T))
(删除节点v(右T)))
(其他
(cond((and(null)(右T))(not(null)(左T)))'())
;将(左T)提升到节点
;重复
((和(空)(左T))(不是(空)(右T)))'())
;将(右T)提升到节点
;重复

要就地删除节点,树必须是可变的-意思是:节点的值、右子树或左子树都可以用新值就地修改

在遍历树时只构建一个新树更容易,但即使如此,也必须做出一些实现选择。下面是一个解决方案的示意图:

(define (delete-node v T)
  (cond ((null? T) '())
        ((< v (value T))
         ; see how we build the new tree
         (make-node (value T)
                    (delete-node v (left T))
                    (right T)))
        ((> v (value T))
         ; see how we build the new tree
         (make-node (value T)
                    (left T)
                    (delete-node v (right T))))
        (else
         (cond ((and (null? (right T)) (and (null? (left T))))
                ; this case was missing
                '())
               ((and (null? (right T)) (not (null? (left T))))
                (left tree))
               ((and (null? (left T)) (not (null? (right T))))
                (right tree))
               (else
                ; implementation detail: if both subtrees of the
                ; node to be deleted are non-null, who should take
                ; the place of the deleted node? the new subtree
                ; must preserve the order property of the tree
                <???>)))))
(定义(删除节点v T)
(cond((null?T)“”())
(v(值T))
;看看我们如何建造这棵新树
(生成节点(值T)
(左T)
(删除节点v(右T)))
(其他
(cond((和(null)(右T))(和(null)(左T)))
;这个案子不见了
'())
((和(空)(右T))(不是(空)(左T)))
(左树)
((和(空)(左T))(不是(空)(右T)))
(右树)
(其他
;实现细节:如果
;要删除的节点不为空,由谁执行
;已删除节点的位置?新子树
;必须保留树的order属性
)))))
有趣的案例标记为
。有几个选项,由您选择并实现一个。例如,在排序树中(我假设这里就是这种情况),可以从左子树中选择最大的元素,并在将其移动到位之前递归删除它


请注意,如果删除节点后树必须保持平衡(根据使用中的平衡定义),算法更复杂-我假设树是不平衡的。

如果需要,我并不反对创建一个新树。对于这段代码,我只是不知道这将如何工作。向我们展示如何构造一个示例树。我是否也应该有一个案例来检查右t和左t是否都为null,然后返回“()”?另外,我可以简单地放置(左t)吗或者(右T)进入else语句?我很难想象为什么这会给我带来问题。我知道我需要左子树中的最大值或右子树中的最小值,但我不知道为什么。1)是的,我更新了我的答案。2)不,如果在上一次
else
3)中这样做,你将删除整个子树因为你必须重新创建一个新的子树,它也会被排序。看看一本好的算法书,或者寻找显示删除过程的在线动画,这会让事情变得清晰