![](/img/trans.png)
[英]Find and revert the swapped nodes in a binary search tree, time requires O(n) and space requires O(h) where h refers to tree depth
[英]Delete multiple nodes from a binary search tree at O(n) time
考虑一个二叉搜索树,其中所有关键字都是唯一的。 节点没有父指针。
我们最多有n / 2个标记节点。
我可以在O(n 2 )时删除所有它们(使用后序遍历,遇到标记节点时,在O(n)删除每个)。 但这是不合适的。 我需要一种算法在O(n)时删除所有标记的节点。 谢谢。
编辑删除后,我需要使节点顺序保持不变。
EDIT-2因此,看起来我已经使用典型的删除操作删除了每个标记的节点(在左侧子树中找到最右边的节点,并将其与要删除的节点交换)。
有很多方法,但是这是应该很容易解决的一种方法,它可以为您提供完美平衡的树作为副作用。 但是,它需要线性的额外空间。
更新:忘了说跳过标记的元素,但这很明显,对吧? ;)
我已经找到了怎么做!
static class LinearDeletion {
public static Node MIN_VALUE = new Node(Integer.MIN_VALUE);;
boolean toFindMax = false;
Node parentOfMax = null;
Node max = MIN_VALUE;
Stack<Object> stack = new Stack<>();
public void perform(Node x, Node parent) {
if (x.isToDelete) {
stack.push(toFindMax);
stack.push(parentOfMax);
stack.push(max);
toFindMax = true;
parentOfMax = null;
max = MIN_VALUE;
if (x.left != null) {
perform(x.left, x);
}
if (x.left == null) { //deletion of the node
if (parent.left == x) {
parent.left = x.right;
} else {
parent.right = x.right;
}
} else {
if (x.right == null) {
if (parent.left == x) {
parent.left = x.left;
} else {
parent.right = x.left;
}
} else {
x.key = max.key;
x.isToDelete = max.isToDelete;
if (parentOfMax != x) {
parentOfMax.right = max.left;
} else {
x.left = max.left;
}
}
} // end of deletion
max = (Node) stack.pop();
parentOfMax = (Node) stack.pop();
toFindMax = (boolean) stack.pop();
if (toFindMax) { // check if the current node is the maximum
if (x.key > max.key) {
max = x;
parentOfMax = parent;
}
}
if (x.right != null) {
perform(x.right, x);
}
} else {
if (x.left != null) {
perform(x.left, x);
}
if (toFindMax) {
if (x.key > max.key) {
max = x;
parentOfMax = parent;
}
}
if (x.right != null) {
perform(x.right, x);
}
}
}
}
我不知道为什么后遍历会是O(n 2 )。 删除单个节点的原因是O(n),因为您需要遍历树以找到该节点,这是O(n)操作。 但是一旦找到一个节点,就可以在O(1)时间内将其删除。 *因此,您可以在O(n)时间内一次遍历删除所有O(n)标记的节点。
*除非您需要维护平衡的树。 但是,您没有将其列为要求。
编辑正如@njlarsson在其注释中正确指出的那样,即使在找到节点之后,删除操作通常也不是O(1)。 但是,由于在访问要删除的节点之前要遍历左右子树,因此在遍历子树期间可以免费获得子树的最小(或最大)元素。 这将启用O(1)删除。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.