我试图在Java中实现Fortune's algorithm,为了避免编写AVLTree,我决定使用带有BeachNode键的TreeMap。 BeachNode具有以下代码:
public abstract class BeachNode implements Comparable<BeachNode>{
static int idcounter=0;
int id;
public StatusNode(){
//Allows for two nodes with the same coordinate
id=idcounter;
idcounter++;
}
@Override
public int compareTo(BeachNode s) {
if(s.getX()<this.getX())
return -1;
if(s.getX()>this.getX())
return 1;
if(s.id<this.id)
return 1;
if(s.id>this.id)
return -1;
return 0;
}
public abstract double getX();
}
Intersection的getX()方法返回一个取决于扫描线当前高度的值 - 因此它会在执行过程中发生变化。
我的第一个问题: (我相当肯定答案是肯定的,但是心安会很好)
如果我确保对于任何两个BeachNodes A和B,signum(A.compareTo(B))保持不变,而A和B在海滩树中,那么即使compareTo背后发生了变化,TreeMap仍会起作用吗?
我的第二个问题:
我如何确保遵守这样的合同?
请注意,在Fortune's algorithm中,我们跟踪两个交叉点将遇到的扫描线位置 - 当扫描线到达其中一个位置时,其中一个交叉点被移除。
这意味着海滩树中的两个交叉点A和B将永远不会交叉位置,但在CircleEvent A.compareTo(B)中将返回0-干扰处理CircleEvent。合同将在CircleEvent期间短暂中断,这将删除一个交叉点。
这是我关于StackOverflow的第一个问题,如果它构成不当或不完整请通知我,我会尽力纠正它。
答案 0 :(得分:1)
根据TreeMap documentation,树将根据compareTo
方法进行排序,因此允许任何未在a.compareTo(b)
的符号中反映的更改。但是,您还需要使用与equals
相同的语义实现compareTo
方法。如果您已经有compareTo
方法,这非常简单:
public boolean equals(Object object) {
if (!(object instanceof BeachNode)) {
return false;
}
BeachNode other = (BeachNode) object;
return this.compareTo(other) == 0;
}
而且,由于您要覆盖equals
,因此您应该覆盖hashCode
。这也很简单,因为您只使用几个字段来定义相等。
public int hashCode() {
int hash = 1;
hash = (17 * hash) + (Double getX()).hashCode());
hash = (31 * hash) + id;
return hash;
}
我不确定你的第二个问题,但由于两个交叉点的id
应该保持不同,它们不相等吗?如果我错了,希望了解算法的人可以帮助你解决这个问题。