我已经浏览了(可能几十个)StackOverflow 问题,但我认为我没有找到我想要的东西。
我想要一个具有以下属性的 Java 结构:
- 已排序
- 可迭代
- 支持泛型
- O(logn)(或更好)的插入和删除
- O(logn)(或更好)元素访问
- 允许重复条目
为什么?我正在实现一个 k-最近距离算法。对于数据集合中的每个点,我需要找到到第 k 个最近的其他点的距离。该算法的工作原理是遍历每对点,计算它们之间的距离,然后如果距离比该列表中的其他元素更近,则将该距离添加到每个点的最近距离的排序结构中。下面是一些代码来演示:
ArrayList<SortedThing<Double>> nearestDistances = new ArrayList<SortedThing<Double>>(numPoints);
for (int i = 0; i < numPoints; i++) {
nearestDistances.add(new SortedThing<Double>(k));
}
for (int point = 0; point < numPoints; point++) {
for (int otherPoint = point+1; otherPoint < numPoints; otherPoint++) {
double distance = computeDistance(point, otherPoint);
if (nearestDistances.get(point).size < k)
nearestDistances.get(point).add(distance);
else if (nearestDistances.get(point).last() > distance) {
nearestDistances.get(point).removeLast();
nearestDistances.get(point).add(distance);
}
if (nearestDistances.get(otherPoint).size < k)
nearestDistances.get(otherPoint).add(distance);
else if (nearestDistances.get(otherPoint).last() > distance) {
nearestDistances.get(otherPoint).removeLast();
nearestDistances.get(otherPoint).add(distance);
}
}
}
在您建议以下任何内置 Java 类之前,这就是我不想使用它们的原因:
- PriorityQueue - 无法访问其中的最后一个元素
- TreeSet - 不允许重复的距离
- ArrayList - 是的,我可以使用 ArrayList,将所有 n-1 距离插入其中,在 O(nlogn) 时间内对其进行排序,然后删除第 k 个元素。但是,这将需要 O(n^2) 空间而不是 O(nk) 空间。
- ArrayList - 或者,我可以维护一个排序的 ArrayList,删除最后一个元素并将新元素插入到正确的位置,但是每次插入需要 O(k) 时间,并且 O(logk) 找到位置插入。
有人知道这样的结构吗?我最近一直在思考这个问题,Java 没有提供任何这样的结构让我感到困惑。