2.2.1 Qt容器类 -- 2017.12.12
发布于:2017-12-12 19:25
2.2.1 QList类、QLinkedList类和QVector类
经常使用的Qt容器类有QList、QLinkedList和QVector等,在开发一个较高性能需求的应用程序时,程序员会比较关注这些容器类
的运行效率。下表列出了QList、QLinkedList和QVector容器的时间复杂度比较
其中,“Amort.O(1)”表示,如果仅完成一次操作,可能会有O(n)行为:但是如果完成多次操作(如n次),平均结果将会是O(1)
QList QLinkedList和QVectoer容器的时间复杂度比较
容器类 查找 插入 头部添加 尾部添加
QList O(1) O(n) Amort.O(1) Amort.O(1)
QLinkedList O(n) O(1) O(1) O(1)
QVector O(1) O(n) O(n) Amort.O(1)
1.QList类
QList<T>是迄今为止最常用的容器类,它存储给定数据类型T的一列数值。继承QList类的子类有QItemSelection、QSignalSpy及QStringList和QTestEventList。
QList不仅提供了可以在列表进行追加的QList::append()和Qlist::prepend()函数,还提供了在列表中间完成插入操作的函数QList::insert()。相对于任何其他的Qt容器类,为了使可执行代码尽可能少,QList被高度优化
QList<T>维护了一个指针组织,该数组存储的指针方向QList<T>存储的列表项的内容。因此,QList<T>提供了基于下标的快速访问
对于不同的数据类型,QList<T>采取不同的存储策略,存储策略有以下几种
(1)如果T是一个指针类型或指针大小的基本类型(即该基本类型占有的字节数和指针类型占有的字节数相同),QList<T>会将数值直接存储在它的数组中。
(2)如果QList<T>存储对象的指针,则该指针指向实际存储的对象
下面举一个例子:
#include<QDebug>
int main
{
QList<QString>list; //(a)
{
QString str("This is a test string");
list<<str; //(b)
}
qDebug()<<list<<"How are you!"; //(c)
return 0;
}
其中,(a)QList<<QString<<list: 声明一个QList<QString>栈对象
(b)list>>str:通过运算操作符“<<”将一个QString字符串存储在该列表中。
(c)程序中使用花括号“{”和“}”括起来的作用域表明,此时QList<T>保存了一个对象的复制
2.QLinkedList类
QLinkedList<T>是一个链式列表,它以非连续的内存块保存数据
QLinkedList<T>不能使用下标,只能使用迭代器访问它的数据项。与QList相比,当对一个很大的列表进行插入操作时,QLinkedList具有更高的效率
3.QVector类
QVector<T>在相邻的内存块中存储给定数据类型T的一组数值,在一个QVector的前部或者中间位置进行插入操作的速度是很慢的,这是因为这样的操作导致内存中的大量数据被移动,这是由QVector存储数据的方式决定的
QVector<T>既可以使用下标访问数据项,也可以使用迭代器访问数据项,继承自QVector类的子类有QPolygon、QPolygonF和QStack
4.Java风格迭代器遍历容器
Java风格的迭代器是Qt4加入的一个功能,同STL风格的迭代器相比,它使用起来更加方便,不过这也是以轻微的性能损耗为代价的,对于每一个容器类,Qt都提供了两种类型的Java风格迭代器数据类型,即只读访问和读写访问。
Java风格迭代器数据类型的两种分类
容器类 只读迭代器类 读写迭代器类
QList<T>,QQueue<T> QListIterator<T> QMutableListIterator<T>
QLinkedList<T> QLinkedListIterator<T> QMutableLinkedListIterator<T>
QVector<T>,QStack<T> QVectorIterator<T> QMutableVectorIterator<T>
Java风格迭代器的迭代点(Java-style iterators point)位于列表项的中间,而不是直接指向某个列表项,因此,它的迭代点或者第一个列表项的前面,或者在两个列表项之间,或者在最后一个列表项之后。
下面以QList为例,介绍Java风格的两种迭代器的用法。QLinkedList和QVector具有和QList相同的遍历接口
实例:通过控制台程序实现QList只读遍历方法,对于Qt的一些类,如QString、QList等,不需要QCoreApplication(对于GUI用户界面程序则使用QApplication)的支持也能够工作,因此本例没有创建QCoreApplication对象,但是,在使用Qt编写应用程序时,如果本例没有创建建议初始化一个QCoreApplication对象;如果是GUI图形用户界面程序,则建议初始化QApplication对象。
代码如下:
#include<QDebug>
int main(int argc,char *argv[])
{
QList<int> list; //创建一个QList<int>栈对象list
list<<1<<2<<3<<4<<5; //用操作运算符“<<”输入五位数
QListIterator<int> i(list); //(b)
for(;i.hasNext();) //(c)
qDebug()<<i.next();
return 0;
}
/*其中,(a)头文件<QDebug>中已经包含了QList的头文件
(b)QListIterator<int>i(list):以该list为参数初始化一个QListIterator对象i。此时,迭代点处在第一个列表项“1”的前面
(注意,并不是指向该列表项)
(c)for(;i.hasNext();):调用QListIterator<T>::hasNext()函数检查当前迭代点之后是否有列表项,如果有,则调用QListIterator<T>::next()函数进行遍历,next()函数将会跳过下一个列表项(即迭代点将位于第一个列表项和第二个列表项之间,)并返回它跳过的列表项
的内容
*/
最后程序运行的结果为:
1 2 3 4 5
- - - - - - - - - - - 害你加班的bug,就是我写的! - - - - - - - - - - -
0
今日新帖
0
昨日新帖
35
帖子总数
《我的那些事儿》Episode 1——舒振新
达人专区 2016-07-18 11:42
一大波免费课求包养中 ——未来的平面设计狮,上么?
达人专区 2015-11-23 18:43
校招快报 | 10天5院校,就是这么帅!
达人专区 2015-12-02 18:44
这是一个装8人的社红之路
达人专区 2016-03-03 15:00
业精于勤 || 只要肯努力奋斗,就没有不成功的!
达人专区 2016-03-08 19:18
邢帅你这个大骗子!这几年都耗在这里啦!
达人专区 2016-03-13 17:29
特殊的日子,特殊的脚印....
回复:2.2.1 Qt容器类 -- 2017.12.12