当要删除的节点有两个子节点时,请考虑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)
问题是如何证明上述程序不是可交换的。
答案 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涉及相同的过程。也就是说,您替换节点的值并替换叶节点。因此,通常,当您删除具有两个子节点的节点时,唯一的结构更改是您要删除的节点的值的更改,以及删除您用作替换的值的叶节点
所以问题进一步完善:
您能否保证无论删除顺序如何(当您总是删除有两个孩子的节点时),您将始终获得相同的替换节点?
答案(我认为)是肯定的。为什么?以下是一些观察结果:
这不是一个严格的证明;这些只是我所做的一些观察。无论如何,请随意戳破洞!
答案 1 :(得分:2)
在我看来,Vivin的答案中显示的反例是非交换性的唯一情况,并且确实通过限制只能删除有两个孩子的节点来消除它。
但是,如果我们放弃看起来像Vivin的前提之一,也可以消除它,即我们应该尽可能少地遍历正确的子树以找到任何可接受的继任者。相反,如果我们总是将右子树中的最小节点作为后继子进行推广,无论它到底有多远,那么即使我们放宽了删除少于两个孩子的节点的限制,Vivin的结果也是如此
7 / 6如果我们从
开始,就永远不会到达
4 / \ 3 7 / 6
相反,我们首先删除3(没有后继者),然后删除4(以6为继承者),屈服
6 \ 7
与删除顺序相反的情况相同。
删除将是可交换的,并且我认为它总是可交换的,给定我已命名的前提(后继者总是删除节点的右子树中的最小节点)。
我没有提供正式证明,只是列举了一些案例:
如果要删除的两个节点位于不同的子树中,则删除一个节点不会影响另一个节点。只有当它们处于相同的路径时,删除顺序才可能影响结果。
因此,只有当祖先节点及其后代之一都被删除时,才能对交换性产生任何影响。现在,他们的垂直关系如何影响交换?
祖先左子树中的后代。这种情况不会影响交换性,因为后继来自正确的子树,根本不会影响左子树。
祖先右子树中的后代。如果祖先的继承者始终是右子树中的最小节点,那么删除顺序不能改变后继者的选择,无论是什么后代在祖先之前或之后被删除。即使祖先的后继者被证明也是要被删除的后代节点,该后代也被替换为它的下一个最大的节点,并且该后代不能拥有自己的左子树来处理。因此,删除祖先和任何右子树后代将始终是可交换的。
答案 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)
,但它可以在其正确的子树中。所以,这是一团糟。
我试着总结一下。
<强>假设强>:
其他的东西我们可以从假设中推断出来:
successor(A)
,A不是successor(B)
。现在,鉴于此,我认为有4种不同的情况(像往常一样,让我们成为B的祖先):
successor(A)
successor(A)
是B 我认为(但当然我无法证明)案例1,2和4并不重要。
因此,只有在successor(A)
是B删除过程的祖先的情况下,才能进行交换。或者可以吗?
我传球:)
问候。