我试图从方案中的二进制搜索树中删除一个节点,但是我在删除部分代码时遇到了问题。如何在不在方案中创建新树的情况下删除节点值?
(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
答案 0 :(得分:3)
为了就地删除节点,您的树必须是可变的 - 意思是:可以使用新值就地修改节点的值,右子树或左子树。
在遍历它时只需构建一个新树更容易,但即使这样,也必须做出几个实现选择。这是解决方案的草图:
(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
<???>)))))
有趣的案例标有<???>
。有几个选项,由您来选择并实施一个选项。例如,在排序树(我假设在这里是这种情况)中,可以从左子树中选择最大的元素,并在将其移动到位之前递归删除它。
请注意,如果在删除节点后树必须保持平衡(根据使用的平衡定义),算法会更加棘手 - 我假设树不平衡。< / p>