我想创建一个记录来保存有关
的信息在树的节点中。我只会为叶子节点显式存储这些信息,而父节点的信息可以通过组合所有子节点的信息来获得(例如,子节点1有3个对象的A,1个对象的B,子节点2有1个A的对象,C对象的2个对象有4个A对象,1个B对象和2个C)。
从父节点请求此信息时,我会小心不要首先请求,使用和丢弃子节点的信息,然后是其父节点,但向上构造将是一个常见的操作。其他两个常见的操作直接来自我存储的内容:是X类的对象吗?和有多少种X的对象?还有如何存在多种物体?
对象种类表示为整数,对象编号始终为整数值。什么是更好的选择(以及所选择的选择的参数):
std::multiset<int>
,并使用std::multiset::count()
和std::multiset::find()
操作(更容易联合,但元素重复,难以获得完全不同的元素数)std::map<int, std::size_t>
作为关键字和对象数作为值(没有重复元素,std::map::find()
函数存在,size给出正确数量的对象种类存储,但访问非现有元素无意中增加了大小)感谢您的建议!
答案 0 :(得分:7)
要根据比较谓词存储 n 项目的 n 项目,<{1}}分配 n 二进制搜索树节点(*)。 std::multiset
仅分配 k (略大)节点。
当比较谓词可以认为两个项目相等时,您可以使用std::map
,但仍必须明确存储,因为它们在比较谓词不检查的某些方面有所不同。此外,迭代std::multiset
生成每个 n 项,而multiset
将生成每个 k 不同的项目,其中包含每个
如果项目只是整数,请使用map
。您的“多少个不同的项目”查询将只是对std::map
的调用,该调用会在固定的时间内运行。
您声称“访问不存在的元素会无意中增加大小”仅在您使用size
访问节点时才会出现。 find
不会出现此行为。
(*)C ++标准并不保证这些容器是作为(平衡的)BST实现的,但在我见过的所有实现中,它们都是。
答案 1 :(得分:2)
排序std::vector<int>
怎么样?您需要的操作可以满足如下:
std::binary_search
std::equal_range
,从.first
减去.second
std::unique_copy
后跟size()
副本,或者...... std::binary_search
与树状结构相比,此方法的优点是缓存局部性(所有数据都是连续的)和更低的内存占用。在不了解您的数据的情况下,我无法确定它是更快还是更慢。你必须对它进行分析以找出答案,但我有预感,这将比你预期的更好。
这里最大的权衡是表达能力。 std::map
方法可能更好地逻辑地传达您正在做的事情,即对象ID和计数之间的关系。