QList

QList<T> 是一个Qt通用容器类。它存储一序列的值,并且提供基于索引的数据访问方法和快速的插入和删除操作。

QList<T>, QLinkedList<T>, 和 QVector<T>提供类似的功能,这里进行几点概述:

1.     大多数情况下,最好使用QList。它基于索引的API比QLinkedList基于迭代器的API方便。它存储数据的方式也使得它比QVector存取数据的数度快。而且它在可执行文件中扩展的代码也比较少。

2.    需要一个真正的链表,能保证在中间插入数据的时间复杂度是常量的,用迭代器来存钱元素的,那可以用QLinkedList

3.     如果想容器的元素在相邻的内存,可以用QVector。

在内部,QList<T>是一个指向T类型的指针数组。如果T本身是一个指针类型或者不大于指针的基本数据类型,或者如果T是一个Qt共享类,QList<T>在直接将元素保持在指针数组中。对于少于一千个元素的链表,这样的数组表示允许在中间快速的插入,而且运行基于索引的存钱方法。此外,prepend() and append() 操作速度也很快,因为QList在其内部数组的两端预先分配了内存。需要注意的是,对于大于指针的非list 项,每次append 或 insert新的项都需要在堆上分配内存,如果需要这样的大量的插入和添加操作,这时最好选择QVector,因为QVector在单一的堆上分配内存。

需要注意的是:在list的生命期中,内部数组只有可能变大,不可能缩小。内部数组只能有析构函数释放或者当用一个list赋值给另外的list时,由赋值函数释放。

为了使QList尽可能高效,它的成员函数不验证输入的有效性。除了isEmpty()之外,其他的成员函数都假定list是非空的。使用索引参数的成员函数总是假定索引值是在有效的范围的。这意味着QList的函数可能调用失败。如果你在编译时定义了QT_NO_DEBUG,则将不会捕获这样的失败。如果没有定义QT_NO_DEBUG, Q_ASSERT() or Q_ASSERT_X() 将捕获这些失败弹出适当的信息。

为了避免失败,在调用其他成员函数前调用isEmpty()。如果成员函数用到索引参数,要检查索引是否在有效的范围。

和QVector类似,QList也是用的隐式共享。

QList<int>integerList;

integerList.push_back(1);

integerList.append(5);

//integerList.setSharable(false);

QList<int>List(integerList);

//List= integerList;

//integerList.setSharable(false);

cout<<"&List.at(0):"<<&List.at(0)<<endl;

cout<<"&integerList.at(0):"<<&integerList.at(0)<<endl;

integerList.setSharable(false);取消注释之后显示的地址就不一样了

std::list

std::list是一种顺序容器,它允许在其中的任何位置进行插入和删除操作,而且可以双向迭代。

List容器实现为双向链表,双向链表可以在不同而且不相关的位置进行存储其元素。其关联的顺序由一个指向前面元素的链接和一个指向后面元素的链接来保持的。

List类似于forward_list。最主要的不同就是forward_list是单链表,所以它只能前向迭代,因此也更小和更高效。

和其他基本的标准容器 (arrayvector and deque)相比,list在插入,提取,移动数据方面更高效,因此在密集的算法中一般都用list,比如排序算法。

和其他顺序容器相比,listsand forward_lists最大的缺点就是缺少通过位置直接存取元素的方法;它们也需要额外的内存来保持链接的信息。

QList 和std::list比较

构造函数:

QList构造函数:

QList::QList ()

QList::QList ( constQList<T> & other )

List构造函数:

C++98版:

explicit list (constallocator_type& alloc = allocator_type());

explicit list (size_type n, const value_type& val = value_type(), const allocator_type& alloc = allocator_type());
template <class InputIterator> list (InputIterator first, InputIterator last,
const allocator_type& alloc = allocator_type());
list (const list& x);

C++11版:

explicit list (const allocator_type& alloc = allocator_type());
explicit list (size_type n); 
list (size_type n, const value_type& val,  const allocator_type& alloc = allocator_type());
template <class InputIterator> list (InputIterator first, InputIterator last,
                                    const allocator_type& alloc = allocator_type());
list (const list& x);
list (const list& x, const allocator_type& alloc);
list (list&& x);
list (list&& x, const allocator_type& alloc);
list (initializer_list<value_type> il,
       const allocator_type& alloc = allocator_type());

QList的构造函数只有默认构造函数和拷贝构造函数两种,std::list的构造函数就比较多了。

QList特有的函数:

void QList::append ( const T & value )           在链表的末尾插入value

void QList::append ( constQList<T> & value )     在链表的末尾插入链表value的元素

该函数实际上调用了QList<T> &

operator+= ( const QList<T> & other )

bool QList::contains ( const T& value ) const      判断链表是否包含元素value

int QList::count ( const T& value ) const          统计链表中值为balue的元素个数

void QList::move ( int from,int to )   把索引为from的值移到索引为to的位置

QList<QString> list;

list << "A" <<"B" << "C" << "D" <<"E" << "F";

list.move(1, 4);

// list: ["A", "C","D", "E", "B", "F"]

有关删除的一些操作:

void QList::removeAt (int i )

bool QList::removeOne ( const T & value )

void QList::removeFirst ()

void QList::removeLast ()

T QList::takeAt ( int i )

T QList::takeFirst ()

T QList::takeLast ()

与其他类型容器的转换方式:

QSet<T> QList::toSet () const

std::list<T> QList::toStdList ()const

QVector<T> QList::toVector () const

支持的操作符运算:

bool QList::operator!= ( constQList<T> & other ) const

QList<T> QList::operator+ (const QList<T> & other ) const

QList<T> & QList::operator+=( const QList<T> & other )

QList<T> & QList::operator+=( const T & value )

QList<T> &QList::operator<< ( const QList<T> & other )

QList<T> &QList::operator<< ( const T & value )

QList<T> & QList::operator=( const QList<T> & other )

bool QList::operator== ( constQList<T> & other ) const

T & QList::operator[] ( int i )

const T & QList::operator[] ( int i ) const

QDataStream & operator<< ( QDataStream & out, const QList<T> & list )

QDataStream & operator>> ( QDataStream & in, QList<T> & list )

Std::list特有的函数:

SpliceC++98版:

void splice (iterator position, list& x);
void splice (iterator position, list& x, iterator i);
void splice (iterator position, list& x, iterator first, iterator last);

C++11版:

void splice (const_iterator position, list& x);
void splice (const_iterator position, list&& x);
void splice (const_iterator position, list& x, const_iterator i);
void splice (const_iterator position, list&& x, const_iterator i);
void splice (const_iterator position, list& x, const_iterator first, const_iterator last);
void splice (const_iterator position, list&& x, const_iterator first, const_iterator last);

该函数个功能是:把链表x的元素,从x中转移到该链表中,从位置position进行插入。该操作不会调用任何元素的构造函数或析构函数。会同时改变这两个链表的大小。

std::list<int>mylist1, mylist2;

std::list<int>::iteratorit;

for(int i=1; i<=4; ++i)

mylist1.push_back(i);

for(int i=1; i<=3; ++i)

mylist2.push_back(i*10);

it =mylist1.begin();

++it;

mylist1.splice(it, mylist2);

cout<<"mylist1.size():"<<mylist1.size()<<endl;

cout<<"mylist2.size():"<<mylist2.size()<<endl;

it =mylist1.begin();

cout<<"mylist1:";

for(it; it !=mylist1.end(); ++it)

{

cout<<*it<<" ";

}

cout<<endl;

it =mylist2.begin();

cout<<"mylist2:";

for(it; it !=mylist2.end(); ++it)

{

cout<<*it<<" \t";

}

sort操作

void sort();
template <class Compare>
  void sort (Compare comp);
版本1用的是 < 比较操作,版本2用comp 进行比较。这两个排序进行的是严格的弱排序。对与相同的值是稳定的,排序后相对位置不变。元素在容器中进行移动,整个过程不会调用任何构造函数,析构函数或拷贝任何元素。

Unique操作:

void unique();
template <class BinaryPredicate>
  void unique (BinaryPredicate binary_pred);
不带参数的版本1会删除每一组相同值的除了第一个元素之外的元素,例如,有连续的几个值为 a  a  a,它会删除后面的两个a,值保留第一个a。
版本2用binary_pred作为比较函数,需要注意的是,该函数会为每个比较对调用binary_pred(*i,*(i-1)),如果比较返回true则会从链表中删除i。

boolsame_integral_part (double first, double second)

{

return ( int(first)==int(second) );

}

structis_near

{

bool operator() (double first, doublesecond)

{

return(fabs(first-second)<5.0);

}

};

double mydoubles[]={ 12.15,  2.72, 73.0, 12.77,  3.14,

12.77, 73.35, 72.25,15.3,  72.25 };

std::list<double> mylist(mydoubles,mydoubles+10);

mylist.sort();

std::list<double>::iterator it =mylist.begin();

cout<<"after sort() mylist:";

int i = 0;

for (it; it != mylist.end(); ++it, ++i)

{

cout<<*it<<"  ";

if (i == 5)

{

cout<<endl;

}

}

cout<<endl;

mylist.unique();

it = mylist.begin();

cout<<"after unique() mylist:";

for (it; it != mylist.end(); ++it)

{

cout<<*it<<"  ";

}

cout<<endl;

mylist.unique (same_integral_part);

it = mylist.begin();

cout<<"after unique(same_integral_part) mylist :";

for (it; it != mylist.end(); ++it)

{

cout<<*it<<"  ";

}

cout<<endl;

mylist.unique (is_near());

it = mylist.begin();

cout<<"after unique(same_integral_part) mylist :";

for (it; it != mylist.end(); ++it)

{

cout<<*it<<"  ";

}

cout<<endl;

merge 操作:

C++98版本:
void merge (list& x);
template <class Compare>
  void merge (list& x, Compare comp);
 
C++11版本:
void merge (list& x);
  void merge (list&& x);
template <class Compare>
void merge (list& x, Compare comp);
template <class Compare>
  void merge (list&& x, Compare comp);
该函数把x的元素按适当的顺序合并到链表中,前提是两个链表都是已经排序了的。
该操作会移除x中的元素插入到链表中,和splice一样,它不会调用构造函数或者析构函数,仅仅是做了转移而已。
版本2指定了一个比较操作函数,它对元素进行严格的弱排序。调用该函数,链表必须是已经排序的,对于没有排序的链表,可以用splice。
对于相同的值也是稳定的,其位置和在x中的相对位置一样。

boolmycomparison (double first, double second)

{

return ( int(first)<int(second) );

}

std::list<double>first, second;

first.push_back (3.1);

first.push_back (2.2);

first.push_back (2.9);

second.push_back (3.7);

second.push_back (7.1);

second.push_back (1.4);

first.sort();

second.sort();

first.merge(second);

// (second is now empty)

second.push_back (2.1);

first.merge(second,mycomparison);

std::cout << "after mergefirst contains:";

for (std::list<double>::iteratorit=first.begin(); it!=first.end(); ++it)

std::cout << ' '<< *it;

std::cout << '\n';

std::cout << "after mergesecond contains  size:"<<second.size()<<endl;

如果我们尝试把排序的两句代码注释掉,则会弹出失败的断言信息。在merge函数中会检查链表是否已经排序。

first.sort();

second.sort();

reverse操作:

C++98版本:

void reverse();

C++11版本:

void reverse() noexcept;

该函数对链表进行反转。

std::list<int>mylist;

for (int i=1; i<10; ++i)

mylist.push_back(i);

std::cout << " beforereverse mylist contains:"<<endl;

for (std::list<int>::iteratorit=mylist.begin(); it!=mylist.end(); ++it)

std::cout << ' '<< *it;

std::cout << '\n';

mylist.reverse();

std::cout << "after reversemylist contains:"<<endl;

for (std::list<int>::iteratorit=mylist.begin(); it!=mylist.end(); ++it)

std::cout << ' '<< *it;

std::cout << '\n';

http://blog.csdn.net/hai200501019/article/details/11747475

QList 和std::list的比较的更多相关文章

  1. Qt之Concurrent框架

    简述 QtConcurrent命名空间提供了一个高级API来编写多线程程序,而无需使用低级线程原语,例如:互斥.读写锁.等待条件或信号量.使用QtConcurrent编写的程序使用的线程数量会自动根据 ...

  2. Qt Thread

    Threading Classes (Qt help manual key words) These Qt Core classes provide threading support to appl ...

  3. Understand the Qt containers(有对应表)

    Container classes are one of the cornerstones of object-oriented programming, invaluable tools that ...

  4. 【NX二次开发】NX内部函数,libuifw.dll文件中的内部函数

    本文分为两部分:"带参数的函数"和 "带修饰的函数". 浏览这篇博客前请先阅读: [NX二次开发]NX内部函数,查找内部函数的方法 带参数的函数: void U ...

  5. QLinkedList和std::forward_list

    forward_list forward_list是C++11版本才有的.forward_list被实现为单链表,而list是一个双向链表,所以forward_list要比list高效一些.forwa ...

  6. QLinkedList和std::forward_list(都是双向链表,不支持operator[],好处可能是插入和删除都比较快)

    forward_list forward_list是C++11版本才有的.forward_list被实现为单链表,而list是一个双向链表,所以forward_list要比list高效一些.forwa ...

  7. 关于QList<T>的内存释放

    当T为指针类型时,List.clear()不能释放其内存,需加上qDeleteAll()函数, //class Person ---> Person(int id_,QString name_) ...

  8. Qt使用std::sort进行排序

    参考: https://blog.csdn.net/u013346007/article/details/81877755 https://www.linuxidc.com/Linux/2017-01 ...

  9. 4.QList

    #include "mainwindow.h" #include <QApplication> #include <QLabel> #include < ...

随机推荐

  1. Windows Server 2012 安装dll到GAC

    使用Windows管理员打开PowerShell: 运行以下命令: Set-location "c:\tools\gac" [System.Reflection.Assembly] ...

  2. SQL中的Update、delete与inner join 联合使用

    Update XXX set XXX where 这种写法大家肯定都知道,才发现update和delete居然支持inner join的update方式,太神奇了. update的格式是 update ...

  3. Tableau 群集部署

    由于公司连续两个月月底Tableau服务器过载崩溃,因此有了搭建Tableau服务器群集的想法.目前还在测试阶段,所以做一步写一步了. 目录: 一.安装和配置工作服务器 二.其他参考文档 一. 安装和 ...

  4. win7如何快速设置开机启动项?

    添加开机启动项方法: 找到windows开始菜单->所有程序->启动,右键打开, 进入C:\Users\Ocean\AppData\Roaming\Microsoft\Windows\St ...

  5. python之filter过滤器

    Python内建的filter()函数用于过滤序列. 和map()类似,filter()也接收一个函数和一个序列.和map()不同的时,filter()把传入的函数依次作用于每个元素,然后根据返回值是 ...

  6. C++的发展,特点和源程序构成

    最近一段时间在学习C++,也借了几本相关的书籍.因为之前主要用C#写程序,大概写了也有两年了吧.所以在回过头来学习C++,还是挺快的.但是我觉得光看书是不行的,要写!!因此我想把我整个学习C++的过程 ...

  7. java键盘录入

    System.out:标准输出设备(默认是:控制台) System.in:标准输入设备(默认是:键盘) --------------------- InputStream in = System.in ...

  8. HTML5 总结-拖放-3

    HTML5 拖放 拖放(Drag 和 drop)是 HTML5 标准的组成部分. 拖放 拖放是一种常见的特性,即抓取对象以后拖到另一个位置. 在 HTML5 中,拖放是标准的一部分,任何元素都能够拖放 ...

  9. 初识 python

    Python 语言介绍 Python 是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言. Python变化 python 2 和 python 3 1.1/2 等于0.5 2.print ...

  10. HttpGet()和HttpPost()

    转 http://www.cnblogs.com/hyddd/archive/2009/03/31/1426026.html Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,P ...