[英]Deletion procedure for a Binary Search Tree
当要删除的节点有两个子节点时,请考虑BST上的删除过程。 假设我总是用在其右子树中保持最小键的节点替换它。
问题是:这个程序是可交换的吗? 也就是说,删除x然后y与删除第一个y然后x?
我认为答案是否定的,但我找不到反例,也没有找出任何有效的推理。
编辑:
也许我必须更清楚。
考虑transplant(node x, node y)
过程:它用y(和它的子树)替换x。 所以,如果我想删除一个有两个子节点的节点(比如说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
/ \
3 7
/
6
如果我们删除4然后删除3怎么办?
当我们删除4时,我们得到6作为新根:
6
/ \
3 7
删除3不会改变树,但是给我们这个:
6
\
7
如果我们删除3然后删除4怎么办?
当我们删除3时,树不会改变:
4
\
7
/
6
但是,当我们现在删除4时,新的根变为7:
7
/
6
产生的两棵树不一样,因此删除不是可交换的。
UPDATE
当你总是删除一个有2个孩子的节点时,我没有读到这个限制。 我的解决方案是针对一般情况的。 如果/当我能找到一个反例时,我会更新它。
另一个更新
我没有具体的证据,但我会冒险猜测:
在一般情况下,根据您是否有两个孩子,一个孩子或没有孩子,您可以不同地处理删除。 在我提供的反例中,我首先删除一个有两个子节点的节点,然后删除一个有一个子节点的节点。 之后,我删除一个没有子节点的节点,然后删除另一个有一个子节点的节点。
在仅删除具有两个子节点的节点的特殊情况下,您需要考虑两个节点都在同一子树中的情况(因为如果它们位于不同的子树中则无关紧要;您可以确定整体结构不会根据删除顺序而改变)。 你真正需要证明的是,在每个节点有两个子节点的同一子树中删除节点的顺序是否重要。
考虑两个节点A和B,其中A是B的祖先。然后,您可以进一步细化问题:
当您考虑从二进制搜索树中删除两个具有祖先 - 后代关系的节点时,删除是否可交换(这意味着它们在同一个子树中)?
当您删除节点(假设为A)时,您将遍历右侧子树以查找最小元素。 此节点将是叶节点,并且永远不能等于B(因为B有两个子节点,不能是叶节点)。 然后,您将使用此叶节点的值替换A的值。 这意味着树的唯一结构变化是用叶节点的值替换A的值,以及叶节点的丢失。
B涉及相同的过程。也就是说,您替换节点的值并替换叶节点。 因此,通常,当您删除具有两个子节点的节点时, 唯一的结构更改是要删除的节点的值的更改,以及删除您用作替换的值的叶节点 。
所以问题进一步完善:
您是否可以保证无论删除顺序如何(当您总是删除有两个孩子的节点时),您将始终获得相同的替换节点?
答案(我认为)是肯定的。 为什么? 以下是一些观察:
这不是一个严格的证据; 这些只是我所做的一些观察。 无论如何,随意戳洞!
在我看来,Vivin的答案中显示的反例是非交换性的唯一情况,并且确实通过限制只能删除有两个孩子的节点来消除它。
但是如果我们抛弃看起来像Vivin的前提之一的话,它也可以被消除,这就是我们应该尽可能少地遍历正确的子树以找到任何可接受的继任者。 相反,如果我们总是将右子树中的最小节点作为后继子进行推广,无论它到底有多远,那么即使我们放宽了删除少于两个孩子的节点的限制,Vivin的结果也是如此
7 / 6如果我们开始,永远不会达到
\n 4\n / \\\n 3 7\n /\n 6\n
相反,我们首先删除3(没有后继者),然后删除4(6作为后继者),屈服
\n 6\n \\\n 7\n
这与删除顺序相反是一样的。
删除将是可交换的,并且我认为它总是可交换的,给定我已命名的前提(后继者总是删除节点的右子树中的最小节点)。
我没有提供正式证明,只是列举了一些案例:
如果要删除的两个节点位于不同的子树中,则删除一个节点不会影响另一个节点。 只有当它们处于相同的路径时,删除顺序才可能影响结果。
因此,只有当祖先节点及其后代之一都被删除时,才能对交换性产生任何影响。 现在,他们的垂直关系如何影响交换?
祖先左子树的后裔。 这种情况不会影响交换性,因为后继来自正确的子树,并且根本不会影响左子树。
祖先右子树中的后裔。 如果祖先的后继者始终是右子树中的最小节点,那么无论在祖先之前还是之后删除了什么后代,删除顺序都不能改变后继者的选择。 即使祖先的后继者被证明是也将被删除的后代节点,该后代也被替换为它的下一个最大节点,并且该后代不能拥有其自己的左子树继续被处理。 因此,删除祖先和任何右子树后代将始终是可交换的。
我认为有两种同样可行的删除节点的方法,当它有2个子节点时:
跳到案例4 ......
案例1:删除3(叶节点)
2 3
/ \\ - > / \\
1 3 1
案例2:删除2(左子节点)
2 3
/ \\ - > / \\
1 3 1
案例3:删除2(右子节点)
2 2
/ \\ - > / \\
1 3 3
______________________________________________________________________
案例4:删除2(左右子节点)
2 2 3
/ \\ - > / \\或/ \\
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
我在此回应Vivin的第二次更新。
我认为这是一个很好的重写问题:
当您考虑从二进制搜索树中删除两个具有祖先 - 后代关系的节点时,删除是否可交换(这意味着它们在同一个子树中)?
但下面这个大胆的句子不是真的:
当您删除节点(假设为A)时,您将遍历右侧子树以查找最小元素。 该节点将是叶节点 ,永远不能等于B.
因为A右子树中的最小元素可以有一个正确的子元素。 所以,它不是一片叶子。 让我们调用A的右子树successor(A)
的最小元素。 现在,B确实不能成为successor(A)
,但它可以是正确的子树。 所以,这是一团糟。
我试着总结一下。
假设 :
我们可以从假设中推断出的其他东西 :
successor(A)
,A不是successor(B)
。 现在,鉴于此,我认为有4种不同的情况(像往常一样,让我们成为B的祖先):
successor(A)
的祖先successor(A)
successor(A)
是B的祖先 我认为(但当然我无法证明)案例1,2和4并不重要。 因此,只有在successor(A)
是B删除程序的祖先的情况下才能进行交换。 或者可以吗?
我传球:)
问候。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.