我正在编写一个空间数据结构,我怀疑最好的NODE实现是什么。 根据我的设计,我有一个抽象节点实体和三个继承它的类:EMPTYNODE,FULLNODE,INTERNALNODE。
第一个没有特定数据。
第二个引用了一个泛型元素。
第三个对其他节点有2个引用。
我找到了几种方法来实现这种情况(我已编码),但我无法确定哪种方法最好。
我发现的第一个解决方案是使用单个类Node,它可能以这种方式执行所有操作:
private static class Node {
private Elem elem = null;
private Node left = null, right = null;
public Elem getElem() {
assert isFull();
return elem;
}
public boolean isEmpty() {
return elem == null && left == null;
}
public boolean isFull() {
return elem != null;
}
public boolean isInternal() {
return elem == null && left != null;
}
}
第二个解决方案是按类编写显式除法,其中每个类仅提供其方法。显然,通过这种方式,我们不得不对节点对象执行多次转换。
private static abstract class Node {
public abstract boolean isEmpty();
public abstract boolean isFull();
public abstract boolean isInternal();
}
private static class FullNode extends Node{
private ITriangle elem;
@Override
public boolean isEmpty() {
return false;
}
@Override
public final boolean isFull() {
return true;
}
@Override
public final boolean isInternal() {
return false;
}
public Elem getElem() {
return elem;
}
}
第三种解决方案是使用继承允许每个类提供所有方法,但是对象类型应该通过“isEmpty()”和类似的方法来检查。如果拨打错误,我们会抛出异常。
private static abstract class Node {
public abstract boolean isEmpty();
public abstract boolean isFull();
public abstract boolean isInternal();
public abstract Elem getElem();
}
private static class Empty extends Node{
@Override
public boolean isEmpty() {
return true;
}
@Override
public final boolean isFull() {
return false;
}
@Override
public final boolean isInternal() {
return false;
}
@Override
public Elem getElem() {
throw new AssertionError();
}
}
您如何看待这三种解决方案?
你会使用哪一个?
任何想法将不胜感激。
答案 0 :(得分:1)
答案取决于节点的使用方式。一旦创建了一个节点,它是否需要从空变为内部变为满,或者它是不可变的吗?
如果节点是不可变的,那么从给出的选项中,如果您希望内部状态发生变化,我会选择选项3,然后选择1。
如果你想要一个行为会改变的可变节点,我会看一下使用Node类来保存带有枚举的数据以保存状态,然后节点会委托给它的实现的相应枚举。例如:
public class Node {
private enum NodeState {
/* each state overrides specific methods to implement custom behaviour */
FULL { public boolean isFull() { return true; } },
INTERNAL { public boolean isInternal() { return true; } },
EMPTY { public boolean isEmpty() { return true; } };
/* the default behaviour */
public boolean isFull() { return false; }
public boolean isEmpty() { return false; }
public boolean isInternal() { return false; }
}
private NodeState state = NodeState.EMPTY;
private Elem elem = null;
private Node left = null, right = null;
public Elem getElem() {
assert isFull();
return elem;
}
/* TODO: constructors/mutators implement state changes go here */
public boolean isEmpty() {
return state.isEmpty();
}
public boolean isFull() {
return state.isFull();
}
public boolean isInternal() {
return state.isInternal();
}
}
class Elem {
/* implementation of this class */
}