为什么C++ map find()具有对数复杂度?

2ekbmq32  于 2023-06-25  发布在  其他
关注(0)|答案(1)|浏览(122)

如果我理解正确的话,因为std::map使用二叉树来维护其排序,所以它具有对数复杂度查找。那么,为什么不使用像std::unordered_map这样的哈希表来实现呢?
创建自己的数据结构(一个无序Map,其中值是链表中的节点)的缺点是什么?
插入将是使用无序Map键对列表进行二进制搜索,并且为了从节点检索数据,我将使用具有常量时间的无序Map键访问节点。
如果这是合理的,有没有更简单的解决方案?
编辑:为我的用例添加一些上下文我需要一个存储项目的结构,每个项目都有一个价格和一个唯一的ID,这样它们就可以按价格排序,在添加或删除项目时应该保持排序。
我最初的想法是将它们存储在一个向量中,并有一个单独的unordered_map,它将每个IDMap到向量的一个in迭代器,这样我就可以用常数时间从向量中删除项目,并用对数时间添加项目,由于排序而无法转义。
现在我知道这是行不通的,因为当添加或删除Item时,向量迭代器会失效。
所以我需要一个稳定的数据结构(在内存中可能不是连续的),它有索引,可以排序,这就是为什么我认为我可以使用Map,同时保留O(1)查找。

nx7onnlm

nx7onnlm1#

创建自己的数据结构(一个无序Map,其中值是链表中的节点)的缺点是什么?插入将是使用无序Map键对列表进行二进制搜索,并且为了从节点检索数据,我将使用具有常量时间的无序Map键访问节点。如果这是合理的,有没有更简单的解决方案?
没有办法回避这样一个事实,即插入到一个有序的、基于比较的关联容器中是一个O(log n)操作。为了证明,请注意,如果你可以在O(1)时间内插入到这样的容器中,那么你可以在O(n)时间内执行基于比较的排序,方法是将项目复制到容器中,然后按排序顺序将它们复制回来。
正因为如此,不清楚你到底在提议什么。当然,在某些情况下,在某个键 k 上维护一个哈希表到一个不使用 k 作为键的二叉树的值是有意义的;例如,如果您希望按姓名排序的人的记录,但也能够在恒定时间内按电话号码查找记录。但是,这类事情并没有绕过按名称插入将是O(log n)的问题。您只需要维护两个关联容器,但通过共享值记录来节省空间。这一点也不神奇

相关问题