二进制搜索树的删除过程

时间:2010-06-07 14:46:24

标签: algorithm data-structures binary-tree binary-search-tree

当要删除的节点有两个子节点时,请考虑BST上的删除过程。假设我总是用在右子树中保存最小键的节点替换它。

问题是:这个程序是可交换的吗?也就是说,删除x然后y具有与删除第一个y然后x?

相同的结果

我认为答案是否定的,但我找不到反例,也没有找出任何有效的推理。

编辑:

也许我必须更清楚。

考虑transplant(node x, node y)过程:它将y替换为y(及其子树)。 所以,如果我想删除一个有两个子节点的节点(比如说x),我用它右边子树中保存最小键的节点替换它:

y = minimum(x.right)
transplant(y, y.right) // extracts the minimum (it doesn't have left child)
y.right = x.right
y.left = x.left
transplant(x,y)

问题是如何证明上述程序不是可交换的。

4 个答案:

答案 0 :(得分:19)

删除(一般情况下)不可交换。这是一个反例:

    4
   / \
  3   7
     /
    6

如果我们删除4然后删除3会怎样?

当我们删除4时,我们得到6作为新根:

   6
  / \
 3   7

删除3不会改变树,但是给我们这个:

  6
   \
    7

如果我们删除3然后删除4怎么办?

当我们删除3时,树不会改变:

 4
  \
   7
  /
 6

但是,当我们现在删除4时,新的根变为7:

  7
 /
6

两个结果树不一样,因此删除不是可交换的。

<强>更新

当你总是删除一个有2个孩子的节点时,我没有读到这个限制。我的解决方案是针对一般情况的。如果/当我能找到一个反例时,我会更新它。

另一个更新

我没有具体的证据,但我会冒险猜测:

在一般情况下,根据您是否有两个孩子,一个孩子或没有孩子,您可以不同地处理删除。在我提供的反例中,我首先删除一个有两个子节点的节点,然后删除一个有一个子节点的节点。之后,我删除一个没有子节点的节点,然后删除另一个有一个子节点的节点。

在仅删除具有两个子节点的节点的特殊情况下,您需要考虑两个节点都在同一子树中的情况(因为如果它们位于不同的子树中则无关紧要;您可以确保整体结构不会根据删除顺序而改变)。你真正需要证明的是,在每个节点有两个子节点的同一子树中删除节点的顺序是否重要。

考虑两个节点A和B,其中A是B的祖先。然后,您可以进一步细化问题:

当您考虑从二进制搜索树中删除两个具有祖先 - 后代关系的节点时,删除是否可交换(这意味着它们位于同一子树中)?

删除节点(假设为A)时,遍历右侧子树以查找最小元素。此节点将是叶节点,并且永远不能等于B(因为B有两个子节点,不能是叶节点)。然后,您将使用此叶节点的值替换A的值。这意味着树的唯一结构变化是用叶节点的值替换A的值,以及丢失叶节点。

B涉及相同的过程。也就是说,您替换节点的值并替换叶节点。因此,通常,当您删除具有两个子节点的节点时,唯一的结构更改是您要删除的节点的值的更改,以及删除您用作替换的值的叶节点

所以问题进一步完善:

您能否保证无论删除顺序如何(当您总是删除有两个孩子的节点时),您将始终获得相同的替换节点?

答案(我认为)是肯定的。为什么?以下是一些观察结果:

  • 假设您先删除后代节点,然后再删除祖先节点。删除后代节点时修改的子树在祖先节点的右子节点的左子树中是。这意味着此子树不受影响。这也意味着无论删除顺序如何,都会修改两个不同的子树,因此操作是可交换的。
  • 再次,假设您先删除后代节点,然后再删除祖先节点。删除后代节点时修改的子树是在祖先节点的右子节点的左子树中。但即使在这里,也没有重叠。原因是当您首先删除后代节点时,您会查看后代节点的 right 子节点的左子树。然后当你删除祖先节点时,从不下去那个子树,因为你输入祖先节点的右边孩子的左边后总是向左移动子树。所以,无论你先删除什么,你都要修改不同的子树,所以看起来顺序并不重要。
  • 另一种情况是,如果首先删除祖先节点,并且发现最小节点是子节点的子节点。这意味着后代节点将以一个子节点结束,删除一个子节点是微不足道的。现在考虑在这种情况下,您首先删除了后代节点的情况。然后,您将使用其右子项替换子节点的值,然后删除正确的子项。然后,当您删除祖先节点时,您最终会找到相同的最小节点(旧的已删除节点的左子节点,也是替换节点的左子节点)。无论哪种方式,你最终都会采用相同的结构。

这不是一个严格的证明;这些只是我所做的一些观察。无论如何,请随意戳破洞!

答案 1 :(得分:2)

在我看来,Vivin的答案中显示的反例是非交换性的唯一情况,并且确实通过限制只能删除有两个孩子的节点来消除它。

但是,如果我们放弃看起来像Vivin的前提之一,也可以消除它,即我们应该尽可能少地遍历正确的子树以找到任何可接受的继任者。相反,如果我们总是将右子树中的最小节点作为后继子进行推广,无论它到底有多远,那么即使我们放宽了删除少于两个孩子的节点的限制,Vivin的结果也是如此

    7
   /
  6
如果我们从

开始,就永远不会到达

    4
   / \
  3   7
     /
    6

相反,我们首先删除3(没有后继者),然后删除4(以6为继承者),屈服

    6
     \
      7

与删除顺序相反的情况相同。

删除将是可交换的,并且我认为它总是可交换的,给定我已命名的前提(后继者总是删除节点的右子树中的最小节点)。

我没有提供正式证明,只是列举了一些案例:

  1. 如果要删除的两个节点位于不同的子树中,则删除一个节点不会影响另一个节点。只有当它们处于相同的路径时,删除顺序才可能影响结果。

    因此,只有当祖先节点及其后代之一都被删除时,才能对交换性产生任何影响。现在,他们的垂直关系如何影响交换?

  2. 祖先左子树中的后代。这种情况不会影响交换性,因为后继来自正确的子树,根本不会影响左子树。

  3. 祖先右子树中的后代。如果祖先的继承者始终是右子树中的最小节点,那么删除顺序不能改变后继者的选择,无论是什么后代在祖先之前或之后被删除。即使祖先的后继者被证明也是要被删除的后代节点,该后代也被替换为它的下一个最大的节点,并且该后代不能拥有自己的左子树来处理。因此,删除祖先和任何右子树后代将始终是可交换的。

答案 2 :(得分:1)

我认为有两种同样可行的删除节点的方法,当它有两个孩子时:
跳到案例4 ...

案例1:删除3(Leaf节点)
2 3
/ \ - &gt; / \
1 3 1


案例2:删除2(左子节点)
2 3
/ \ - &gt; / \
1 3 1


案例3:删除2(右子节点)
2 2
/ \ - &gt; / \
1 3 3

<强> ______________________________________________________________________
案例4:删除2(左和右子节点)
2 2 3
/ \ - &gt; / \ 要么 / \
1 3 1 3
同时工作并产生不同的树木:) ______________________________________________________________________
这里解释的算法:http://www.mathcs.emory.edu/~cheung/Courses/323/Syllabus/Trees/AVL-delete.html Deleting a node with 2 children nodes: 1) Replace the (to-delete) node with its in-order predecessor or in-order successor 2) Then delete the in-order predecessor or in-order successor

答案 3 :(得分:0)

我在此回应Vivin的第二次更新。

我认为这是对这个问题的重写:

  

当你是的时候删除是可交换的   考虑删除两个节点   从二进制搜索树中有一个   祖先 - 后裔的关系   彼此(这意味着他们   是在同一个子树)?

但是下面这个粗体句子不是真的:

  

删除节点时(假设是A),   你遍历正确的子树   找到最小元素。 此节点   将是一个叶子节点,永远不能等于B

因为A右子树中的最小元素可以有一个正确的子。所以,它不是一片叶子。 让我们调用A右子树successor(A)中的最小元素。 现在,B不可能是successor(A),但它可以在其正确的子树中。所以,这是一团糟。

我试着总结一下。

<强>假设

  1. A和B各有两个孩子。
  2. A和B属于同一子树。
  3. 其他的东西我们可以从假设中推断出来:

    1. B不是successor(A),A不是successor(B)
    2. 现在,鉴于此,我认为有4种不同的情况(像往常一样,让我们​​成为B的祖先):

      1. B位于A的左子树
      2. B是successor(A)
      3. 的祖先
      4. successor(A)是B
      5. 的祖先
      6. B和继承人(A)没有任何关系。 (他们使用不同的A的子树)
      7. 我认为(但当然我无法证明)案例1,2和4并不重要。 因此,只有在successor(A)是B删除过程的祖先的情况下,才能进行交换。或者可以吗?

        我传球:)

        问候。