删除(通常)不是可交换的。这是一个反例:
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 也涉及相同的过程。也就是说,您替换节点的值并替换叶节点。所以一般来说,当你删除一个有两个子节点的节点时,唯一的结构变化是你正在删除的节点的值的变化,以及你正在用作替换值的叶节点的删除。
于是问题进一步细化:
你能保证无论删除顺序如何(当你总是删除一个有两个孩子的节点时)你总是会得到相同的替换节点吗?
答案(我认为)是肯定的。为什么?以下是一些观察:
- 假设您首先删除后代节点,然后删除祖先节点。删除后代节点时修改的子树不在祖先节点右孩子的左子树中。这意味着该子树不受影响。这也意味着无论删除顺序如何,都会修改两个不同的子树,因此操作是可交换的。
- 同样,假设您首先删除后代节点,然后删除祖先节点。删除后代节点时修改的子树位于祖先节点右孩子的左子树中。但即使在这里,也没有重叠。原因是当你先删除后代节点时,你看的是后代节点右孩子的左子树。然后,当您删除祖先节点时,您将永远不会沿着该子树向下走,因为在您进入祖先节点的右孩子的左子树后,您将始终向左走。同样,无论您首先删除什么,您都在修改不同的子树,因此看起来顺序并不重要。
- 另一种情况是,如果先删除祖先节点,发现最小节点是后代节点的子节点。这意味着后代节点将以一个孩子结束,删除一个孩子是微不足道的。现在考虑在这种情况下,您首先删除了后代节点的情况。然后,您将用其右孩子替换后代节点的值,然后删除右孩子。然后,当您删除祖先节点时,您最终会找到相同的最小节点(旧删除节点的左孩子,也是被替换节点的左孩子)。无论哪种方式,您最终都会得到相同的结构。
这不是一个严格的证明;这些只是我所做的一些观察。无论如何,请随意戳洞!