有一个简单而高效的可能性:
如果您只能在最终填满的学生结构中搜索百分位数,那么:
当您不知道元素的数量时,使用 ArrayList 动态构建。
如果您知道它们,则直接从数组开始,否则从动态数组创建数组。(例如java中的ArrayList)。
插入:不需要,替换为在末尾添加,并排序一次。
删除:没有必要,如果你能忍受的话。
告诉百分位数:更简单:非常接近:元素[长度*百分位数]:O(1)
在实践中,数组方法将比平衡树方法快得多,至少在 java 中,当您的应用程序可以构建一次数组时(例如每日学生评估,每天构建它)
我已经使用自写的 ArrayListInt 实现了(我的)上述算法,它与 ArrayList 相同,但使用原始类型(double、int)而不是对象类型。当所有数据都被读取后,我对其进行了一次排序。
此外,您还需要键值:
我只需添加一个树图(平衡树)。现在有点怀疑 TreeMap 和附加的百分位数数组是否有意义:这取决于您必须搜索的频率,以及内存使用量与搜索时间的关系。
更新:
结果:treeset vs sorted array(动态构建数组,然后最后排序一次:
num elements: 1000 treeSet: 4.55989 array=0.564159
num elements: 10000 treeSet: 2.662496 array=1.157591
num elements: 100000 treeSet: 31.642027 array=12.224639
num elements: 1000000 treeSet: 1319.283703 array=140.293312
num elements: 10000000 treeSet: 21212.307545 array=3222.844045
这个数量的元素(1e7)现在接近限制(1GB 堆空间),在下一步中内存将耗尽(已经发生在 1e7,但是在树集之后清理内存,测量 1e7 的运行也有效。
缺少的是搜索时间,但是带有 binsearch 的排序数组只能被哈希表击败
最后:
如果您可以建立学生集一次,例如每天,那么使用数组方法可以提供更简单的百分位搜索。