STL List和Vector如何实现?
我刚接受采访时被问到这个问题。
我刚才说可能通过使用关于向量的二叉树或哈希表。不确定列表...... 我错了,我猜是这样的.. 感谢一些想法。
答案 0 :(得分:13)
哈希表还是二叉树?为什么呢?
std::vector
,正如名称本身所暗示的那样,是用一个正常的动态分配数组实现的,当它的容量耗尽时(通常是它的大小加倍或类似的东西)重新分配。
std::list
使用双向链表实现(通常是 1 )。
您提到的二叉树是std::map
的通常实现;相反,哈希表通常用于unordered_map
容器(即将推出的C ++ 0x标准中提供)。
std::vector
,标准强制执行“连续空间”要求(从C ++ 03开始),因此它必须是某种形式的动态分配数组。答案 1 :(得分:3)
std::vector
使用连续分配的数组和展示位置new
std::list
使用动态分配的块,指针指向下一个和上一个元素。
没有像二进制树或哈希表那样花哨(可以用于std::map
)
答案 2 :(得分:1)
你可以花半个学期谈论任何一个容器,但这里有几点:
std::vector
是一个连续的容器,这意味着每个元素都紧跟在内存中的前一个元素之后。它可以在运行时增长,这意味着它将其存储分配在动态内存中。
std::list
是一个双向链表。这意味着元素以任意布局分散在内存中,并且每个元素都知道序列中下一个和前一个元素的位置。
std::vector
,std::list
和其他容器不会拥有他们拥有的元素,但他们会自行清理。因此,如果元素是指向动态内存的指针,那么用户必须在容器破坏之前释放指针。但是如果容器包含自动数据,那么数据的析构函数将在容器清理时自动调用。
到目前为止,非常简单,大致相当于任何其他语言或工具集。 STL的独特之处在于容器是泛型并且与迭代它们的方式分离(并且大部分)来自您可以对它们执行的操作。某些操作可以使用某些容器特别有效地完成,因此容器将在这些情况下提供成员功能。例如,std::list
具有sort()
成员函数。
STL不提供容器类(大部分),而是容器模板。换句话说,当库谈论一个容器时,它只是匿名地引用数据类型,比如,T
,而不是它的真实名称。从不int
或double
或Car
;对于任何类型,总是T
。有一些例外,例如std::vector<bool>
,但这是一般情况。然后,当用户实例化容器模板时,它们指定一个类型,编译器根据该类型的模板创建容器类。
STL还提供算法作为免费模板功能。这些算法适用于 iterators ,它们本身就是模板。通常,迭代器成对出现,表示算法运行的序列的开始和结束。 std::vector
,std::list
和其他容器然后公开他们自己的迭代器,可以遍历和操纵他们的数据。因此,相同的自由算法可以在std::vector
和std::list
以及其他容器上工作,前提是迭代器符合有关迭代器能力的特定假设。
所有这些抽象都是在编译时完成的,与其他语言相比,这是最大的区别。这可以通过相对简短的代码转换为出色的性能。与C相同的性能,你只能通过大量的复制粘贴或硬编码。