在stl映射中,关键帧是如何按升序排列的
How are keys arranged in ascending order in stl maps?
当我在for循环中迭代映射时
for(auto it : my_map )
cout << it.first << "n" ;
当数据实际上以平衡树的形式存储时,我如何获得有序列表。这个运算的时间复杂度O(n)是多少?
好问题。map
实际上被实现为平衡树(通常实现选择红黑树)。整个树中的所有节点都包含值(即,不仅仅是叶节点),并且对它们进行排序,使得任何节点的"左"分支只包含"小于"节点自身值的值,而"右"分支包含更大的值。
例如:
m
/
f q
/ /
c h o t
/
g
要遍历树,首先从C开始,它必须由映射对象本身中的指针跟踪,否则开始就不是O(1)。然后,从任何给定的节点开始,迭代只需执行以下3个选项中的第一个即可:
1) 如果你已经在最右边的节点,地图对象也必须跟踪,停止否则
2) 如果有一个转到右子级,则尽可能向下跟随其"左子级"指针,否则
3) 按照链接返回父节点/父节点等,直到你发现你刚刚从中提升的节点是其父节点的左节点(此时父节点的节点值将大于你从中提升到的任何节点;注意,比较指针/链接总是很便宜,所以这比比较键值要好,因为对某些类型来说,键值可能很昂贵)
- 例如,当你将g提升到h时,你将来自左子节点,因此应该在h停止;然后在下一次迭代中,你将首先上升到f,但看到你不是来自左子,所以继续上升f到m,这是来自左子的,所以这将是迭代过程中的下一站
这个运算的时间复杂度O(n)是多少?
假设你在纸上画一棵树,并写下箭头,以显示你是如何使用上面的逻辑遍历这棵树的,你会看到你只有一次沿着任何给定的"左子女/父母"链接下降,然后通过同一链接上升。因此,链路遍历的数量是<2n,并且比较的数量甚至更小——所以很明显O(n)。
如果我正确理解您的问题,您需要按顺序获得映射键的列表。我认为以下方法可行:
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)。
相关文章:
- 按对象的特定方法按升序排列的C++优先级队列
- 为什么我的递归函数按降序打印,然后按升序打印?
- C++ - 将元素按升序插入数组的 SEG 错误
- 按升序对链表进行排序
- 读取一组用户输入,按升序排序,然后打印结果
- 按升序打印矢量的所有元素直到它为空而没有重复项的最有效方法是什么?
- 按升序输出整数时,将最后一个整数放在新行上
- 如何按升序对输入文件中的数字进行排序,并找到它们的范围和中值
- 有没有更简单的方法可以从用户那里获取三个数字并按升序打印它们?
- 编写程序,导入三个浮点数a,b和c.按升序排序
- 按升序对列表进行排序,C++使用气泡排序
- 按升序对数组进行排序嵌套循环问题
- 为什么此函数按升序打印 1 2 3 4 5
- 我在编写从文本文件中读取数据并按升序打印的代码时遇到问题
- 使用相同的 for 循环按升序或降序遍历地图
- 如何按升序将偶数从向量 a 转移到向量 b?
- C 以升级循环时按升序打印数字
- 尝试使用在数组中找到最小值的函数来按升序排序数组
- 按升序打印阵列旨在下降
- 如何检查 2D 数组在 c++ 中是否按升序排列?