[英]How to implement removeAny in the Set ADT for a BST using active flags
我使用带有二进制搜索树的节点(TreeNodes)的标准方法来实现Set ADT。
我的任务是使用相同的旧节点来实现它,除了它们具有一个附加的布尔字段“ active”之外,该字段可以在节点出现时“打开”( setActive(true)
)或“关闭”( setActive(false)
)。除去。 这会将删除的节点保留在那里,但是当我们实现toString()
,它们将被忽略,该方法返回集合中的项。
除了removeAny()
(从集合中删除任何内容,本质上是“将其关闭”)之外,我能够实现Set ADT的所有方法。 问题是我必须找到“打开”的任何节点。 为此,我必须遍历每个节点并检查一个节点是否处于活动状态。 我试图使用递归调用编写代码,但对返回的内容感到困惑。 这是我的尝试(使用Java):
public T removeAny() throws Exception {
if (size == 0) {
throw new Exception ("You cannot remove anything since the set is empty!");
}
return removeAnyHelper (root);
}
public T removeAnyHelper (OnOffTreeNode <T> node) {
if (node == null) {
return root.getValue();
}
if (node.getActive() == true) {
size--;
node.setActive(false);
return node.getValue();
}
removeAnyHelper (node.getLeft());
return removeAnyHelper (node.getRight());
}
如何解决此方法? 我应该退还什么?
我尝试了一些if语句来返回removeAnyHelper (node.getLeft())
和removeAnyHelper (node.getRight())
,但这没有用。
如果节点为null,则可能需要返回null(因为未删除任何内容)。
如果对左子节点的递归调用未返回null,则意味着我们删除了一个节点,需要返回它。 否则,我们需要在正确的子对象上返回调用结果。
将其转换为代码:
public T removeAnyHelper (OnOffTreeNode <T> node) {
if (node == null) {
return null;
}
if (node.getActive()) { // == true is unnecessary
size--;
node.setActive(false);
return node.getValue();
}
T removedNode = removeAnyHelper (node.getLeft());
if (removedNode != null)
return removedNode;
else
return removeAnyHelper (node.getRight());
}
尽管我实际上不建议在BST中为节点使用活动/不活动标志- 删除节点并不是特别困难,并且可以避免拥有大量不活动节点的问题。
更一般地说,还有自平衡BST ,可以避免由于树木不平衡而导致效率降低。
好吧,我认为removeAny
不是Set
的正确方法,但是无论如何。
你可以(而且可能应该) removeAny
通过去除前叶:
private T removeAnyHelper(OnOffTreeNode <T> node) {
if (!present(node.getLeft() && !present(node.getRight())) {
// no children -> this is a leaf, return
node.setActive(false);
return node.getValue();
}
// return left first, or right if left not present
if (present(getLeft())) {
return removeAnyHelper(getLeft());
}
return removeAnyHelper(getRight());
}
private boolean present(OnOffTreeNode<T> node) {
return node != null || node.isActive();
}
请注意,您的基本removeAny
方法也有一个错误,因为它不检查root的活动状态:
public T removeAny() throws NoSuchElementException {
if (size == 0 || !root.isActive()) {
throw new NoSuchElementException ("cant remove");
}
return removeAnyHelper(root);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.