【问题标题】:Deleting a Node in Scheme删除方案中的节点
【发布时间】:2013-10-26 02:16:22
【问题描述】:

我正在尝试从方案中的二叉搜索树中删除一个节点,但在删除部分代码时遇到了问题。如何删除节点值而不在方案中创建新树?

(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

【问题讨论】:

  • 如果我需要为这段代码创建一棵新树,我并不反对,我只是看不出它是如何工作的。
  • 向我们展示如何构建示例树。

标签: recursion scheme binary-tree nodes


【解决方案1】:

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

在遍历它的同时构建一棵新树更容易,但即便如此,也必须做出几个实现选择。这是一个解决方案的草图:

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

有趣的案例标有&lt;???&gt;。有多种选择,您可以选择并实施其中一种。例如,在一棵排序树中(我假设是这种情况),可以从左子树中选择最大的元素,并在将其移动到位之前递归地删除它。

请注意,如果在删除节点后树必须保持平衡(根据使用中的平衡定义),那么算法会比较棘手 - 我假设树不平衡。

【讨论】:

  • 我是不是也应该有一个case来检查右T和左T是否都为null,然后返回'()?另外,我可以简单地将 (left T) 或 (right T) 放入 else 语句中吗?我很难想象为什么这会给我带来麻烦。我知道我需要左子树中的最大值或右子树中的最小值,但我不知道为什么。
  • 1) 是的,我更新了我的答案。 2) 不,如果您在最后一个else 中这样做,您将删除整个子树 3) 因为您必须重新创建一个新的子树,它也已排序。看看一本好的算法书或者找网上的动画来展示删除的过程,就清楚了
猜你喜欢
  • 1970-01-01
  • 2019-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多