简体   繁体   English

清楚函数的时间复杂度是什么std :: map根据大O?

[英]What is the time complexity for a clear function is std::map according to big O?

What is the time complexity for a clear function is std::map? 清除函数的时间复杂度是std :: map是多少?
Would I be right in saying that it is O(1)? 我是否正确地说它是O(1)?

The Standard says in [associative.reqmts]/8 Table 102 : 标准在[associative.reqmts] / 8 表102中说

a.clear() <=> a.erase(a.begin(), a.end()) linear in a.size() a.clear() <=> a.erase(a.begin(), a.end())中线性a.size()

So it is actually mandated to be O(N). 所以它实际上是强制性的O(N)。


EDIT: summing up the various bits. 编辑:总结各个位。

To remove a node, a map does two operation: 要删除节点, map执行两个操作:

  1. Call the allocator destroy method to destroy the element 调用allocator destroy方法来销毁元素
  2. Call the allocator deallocate method to deallocate the memory occupied by the node 调用allocator deallocate方法来释放节点占用的内存

The former can be elided in code (checking for is_trivially_destructible ), and actually it is generally done in vector for example. 前者可以在代码中省略(检查is_trivially_destructible ),实际上它通常在vector完成。 The latter is unfortunately trickier, and no trait exists, so we must rely on the optimizer. 不幸的是,后者更加棘手,并且不存在特征,因此我们必须依赖优化器。

Unfortunately, even if by inlining the optimizer could completely remove the destroy and deallocate nodes, I am afraid it would not be able to realize that the tree traversal is now useless and optimize that away too. 不幸的是,即使通过内联优化可以彻底清除destroy ,并deallocate节点,恐怕将无法认识到树遍历现在是无用和优化的路程了。 Therefore you would end up in a Θ(N) traversal of the tree and nothing done at each step... 因此,你最终会在树的Θ(N)遍历中结束,并且每一步都没有完成任务......

cplusplus参考站点声称它在容器大小上具有线性复杂性,因为必须调用每个元素的析构函数。

Because it's a template, it may be known at compile time that destruction in a no-op for the type (eg std::map<int> ), so the need to destroy members isn't a good basis for deducing a necessary worst-case performance. 因为它是一个模板,所以在编译时可能会知道类型的无操作中的破坏(例如std::map<int> ),因此需要销毁成员并不是推断必要的最差的良好基础 - 表现。 Still, the compiler must visit every node of the binary tree, releasing the heap memory, and the number of nodes relates linearly to the number of elements (that erase() only invalidates iterators/references/pointers to the erased element, insert() doesn't invalidate any etc. all evidence the 1:1 relationship). 仍然,编译器必须访问二叉树的每个节点,释放堆内存,并且节点的数量线性地与元素的数量相关( erase()仅使迭代器/引用/指向无效元素的insert()无效, insert()并不会使所有证据与1:1关系无效。

So, it's linear, but because of the need to clean up the heap usage even if element destructors aren't needed.... 所以,它是线性的,但是由于需要清理堆使用,即使不需要元素析构函数....

(Interestingly, this implies that a std::map<> -like associative container - or perhaps std::map<> itself with a clever custom allocator - could be made O(1) for elements with trivial no-op destructors if all the memory was allocated from a dedicated memory pool that could be "thrown away" in O(1).) (有趣的是,这意味着std::map<> -like关联容器 - 或者std::map<>本身带有一个聪明的自定义分配器 - 可以为具有普通无操作析构函数的元素设置O(1)内存是从专用内存池中分配的,可以在O(1)中“丢弃”。)

据我所知,所有清理操作的复杂性都是O(n),因为你需要逐个去除这些对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM