2.2.1 Qt容器类 -- 2017.12.12

HuRui 发布于 2017/12/12 19:25
查看:670|回复:4

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

               417568d5d25a8a3b4421475496b08745003.gif

  - - - - - - - - - - - 害你加班的bug,就是我写的! - - - - - - - - - - - 

查看点赞情况
全部点赞
总计: --

共有4条评论

发布新贴
招版主啦

版主

  • 西米酱 西米酱
  • xly xly
  • 章鱼哥笔记 章鱼哥笔记

注册有礼

完善以下信息,为你推荐课程

  • 学生
  • 白领
  • 高管
  • 自由职业
  • 其他
  • 工作需要
  • 自我提升
  • 兴趣爱好
  • 创业/转型
  • 其他
  • 小白
  • 了解
  • 熟悉
  • 精通
  • 其他
  • 高中/中专
  • 专科
  • 本科
  • 硕士
  • 其他
  • 影视枪战大片特效解析
  • PS视觉惊悚课堂
  • 45天7千平方大厦变形记
  • 原画学习痛点技法全解析
  • 影视动画奇幻课堂
  • AI高端商业设计全攻略
  • UG职场生存必备指南
  • 日赚千元之新媒体行业揭秘
出现异常