目录
🛫 导读
需求
看qt的文档,只要是不要求数据所存放的内存是连续的,都建议用QList,因为QList的查询速度跟QVecotr是差不多的。感觉有点奇怪,至少与我之前所认识的List的查询是一不样的。
1️⃣ QVector(std::vector)
QVector类是一个提供动态数组的模板类。QVector<T>使用连续内存来保存数据项,分配所需内存的方式与动态内存分配的方式相比,减少了在时间和内存上的开销。
2️⃣ QLinekedList(std::list)
QLinkedList<T>提供一个双向链表,插入删除操作在常数时间完成。
虽然插入、删除操作是常数时间,但 QLinkedList<T>只有在对象数量超过200对象时才能看出优势。对于小于200个对象的链表, QList<T>提供更好的性能、耗费更小的内存。
QLinkedList<T>的优点是数据的插入和删除很快,但是随机位置值的访问会很慢。与QVector<T>不同,QLinkedList<T>并没有提供重载的[]操作符,只能使用append()函数,或者<<操作符进行数据的添加。
3️⃣ QList
QList是典型的数组链表,不是真正意义上的链表。
根据参数T的不同, QList 有两种组织方式。通常情况下, QList 有一个指针数组用于保存用new操作符在堆上分配的对象的指针,使得在容器的中间插入和删除的速度比参数为不可拷贝类型的QVector快,因为指针是可以用内存拷贝。
QList<T>是一个同时拥有QVector<T>和QLinkedList<T>的大多数有点的顺序存储容器类。既可以像QVector<T>一样支持快速的随机访问,重载了[]操作符,提供了索引访问的方式;也可以像 QLinkedList<T>一样,支持快速的添加、删除操作。除非我们需要进行在很大的集合的中间位置的添加、删除操作,或者是需要所有元素在内存中必须连续存储,否则我们应该一直使用Qlist<T>。
🛬 文章小结
QVector & QList
从上文的图中,我们可以看出,的元素的指针是通过数组来管理的,而不是用next的方式。每当插入或者删除一个元素时,QList就会更新这个指针数组。
查询的时候,QList只需要通过下标从此指针数组中找到元素的指针,再通过元素指针找到对应的元素即可。因此其查询复杂度跟QVector一样,也是常数的。只是每次查询比QVector多了一次指针寻址而已(当然QList[idx]的调用方式还会有些不同的)。
可见QList其实不仅仅是一个链表,可以说是一个数组与链表的结合体。
性能差异
容器类 | 查找 | 插入 | 头部添加 | 尾部添加 |
QVector | O(1) | O(n) | O(n) | Amort.O(1) |
QLinkedList | O(n) | O(1) | O(1) | O(1) |
QList | O(1) | O(n) | AmoO(1) | Amort.O(1) |
📖 参考资料
- QT开发(二十五)——QT模板库 https://blog.51cto.com/quantfabric/1873252
-
QT QList<T>介绍与应用、详解、使用说明、官方手册翻译https://blog.csdn.net/u014779536/article/details/111029600