【问题标题】:How are keys arranged in ascending order in stl maps?stl map中的key是如何升序排列的?
【发布时间】:2016-04-30 12:16:03
【问题描述】:

当我在 for 循环中遍历地图时

for(auto it : my_map )
cout << it.first << "\n" ;

当数据实际上以平衡树的形式存储时,我如何获得有序列表。还有这个操作O(n)的时间复杂度如何?

【问题讨论】:

  • 不清楚你在问什么。按顺序遍历一棵树就做好了。给定 N 个结果,复杂度必须至少为 O(N);为什么会更多?
  • @JonathanMee 嗨,我不认为这两个问题是相似的,我很清楚地图是 bst 的实现,我的问题是如何遍历 bst,以便我们以升序排列数据.例如,如果一个数组是 sorted ,我们可以简单地想象遍历 [0]-->[1]-->[2]-->.....-->[n] 。但是在二叉树的情况下,数据根本没有安排得那么简单,让我思考当我们使用上面提到的循环时迭代器如何从一个节点到另一个节点......希望我的问题现在更清楚一点:) .
  • 嗨@AlanStokes 请阅读我对乔纳森的评论。当我知道操作本身时,我只能知道操作的时间复杂度是多少:p,顺便说一句,这也是我的问题,如何遍历 bst 以使我们以升序遍历数据(关于键) 使用给定的 for 循环时。

标签: c++ stl maps


【解决方案1】:

好问题。 map 确实实现为平衡树(通常实现选择红黑树)。整个树中的所有节点都保存值(即不仅仅是叶节点),并且它们被排序使得任何节点的“左”分支只包含“小于”节点自身值的值,而“右”分支包含更大的值价值观。

例如:

           m
         /   \
        f     q
       / \   / \
      c   h o   t
         /
        g

要遍历树,你首先从 C 开始,它必须由映射对象本身中的指针跟踪,否则 begin 不会是 O(1)。然后从任何给定节点,迭代只需执行以下三个适用的选项中的第一个:

1) 如果您已经在最右边的节点,地图对象也必须跟踪该节点,停止; 否则...

2) 如果有一个去右孩子,然后尽可能地跟随它的“左孩子”指针向下,否则......

3) 按照链接返回父/祖父等节点,直到您发现您刚刚上升的节点是其父节点的左节点(此时父节点的值将大于任何您已从中上升的节点;请注意,比较指针/链接始终很便宜,因此这比比较某些类型可能很昂贵的键值要好)

  • 例如,当你将g升到h时,你将来自一个左子节点,所以应该停在h;然后在下一次迭代中,你将首先上升到 f,但看到你不是来自左孩子,所以继续从左孩子上升 f 到 m,所以这将是你迭代期间的下一站

这个操作O(n)的时间复杂度如何?

假设您在纸上画了一棵树并用箭头写出您如何使用上述逻辑遍历树,您会看到在任何给定的“左孩子/父母”链接之后只有一次下降,然后是一次上升通过相同的链接。因此,链接遍历次数

【讨论】:

  • 您好,您的回答正是我想要的 :)...但是我在执行三个步骤时遇到了一些麻烦。根据您编写的步骤,我并没有完全按照我实际应该的方式遍历,即 c-->f-->g-->h-->m...等等(升序)。我还注意到,如果没有正确的孩子,我应该做什么没有任何步骤。 :)
  • @95_96:据我所见,它们确实可以正确遍历 - “如果没有 [was/is] 没有正确的孩子,我应该做什么”表明我没有解释清楚对于迭代器的任何给定增量,您只需遵循适用的三个指令中的第一个就足够了。因此,如果没有合适的孩子,您将进入第 3 步 - 去找父母等……我已经改写了答案,以(希望)更清楚。干杯。
【解决方案2】:

如果我正确理解您的问题,您希望按顺序获取映射键列表。我认为以下方法可行:

std::vector<map_type::key_type> keys;
std::transform(my_map.begin(), my_map.end(), std::back_inserter(keys),
               [](map_type::value_type const& v){return v.first;});

它将在 O(n) 中运行,因为它直接迭代链接的集合。按键查找元素是对数的,但迭代是 O(n)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-16
    • 1970-01-01
    • 2010-10-16
    • 1970-01-01
    • 1970-01-01
    • 2018-12-05
    • 2015-01-31
    • 1970-01-01
    相关资源
    最近更新 更多