QList 和std::list的比较
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是单链表,所以它只能前向迭代,因此也更小和更高效。
和其他基本的标准容器 (array, vector 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的比较的更多相关文章
- Qt之Concurrent框架
简述 QtConcurrent命名空间提供了一个高级API来编写多线程程序,而无需使用低级线程原语,例如:互斥.读写锁.等待条件或信号量.使用QtConcurrent编写的程序使用的线程数量会自动根据 ...
- Qt Thread
Threading Classes (Qt help manual key words) These Qt Core classes provide threading support to appl ...
- Understand the Qt containers(有对应表)
Container classes are one of the cornerstones of object-oriented programming, invaluable tools that ...
- 【NX二次开发】NX内部函数,libuifw.dll文件中的内部函数
本文分为两部分:"带参数的函数"和 "带修饰的函数". 浏览这篇博客前请先阅读: [NX二次开发]NX内部函数,查找内部函数的方法 带参数的函数: void U ...
- QLinkedList和std::forward_list
forward_list forward_list是C++11版本才有的.forward_list被实现为单链表,而list是一个双向链表,所以forward_list要比list高效一些.forwa ...
- QLinkedList和std::forward_list(都是双向链表,不支持operator[],好处可能是插入和删除都比较快)
forward_list forward_list是C++11版本才有的.forward_list被实现为单链表,而list是一个双向链表,所以forward_list要比list高效一些.forwa ...
- 关于QList<T>的内存释放
当T为指针类型时,List.clear()不能释放其内存,需加上qDeleteAll()函数, //class Person ---> Person(int id_,QString name_) ...
- Qt使用std::sort进行排序
参考: https://blog.csdn.net/u013346007/article/details/81877755 https://www.linuxidc.com/Linux/2017-01 ...
- 4.QList
#include "mainwindow.h" #include <QApplication> #include <QLabel> #include < ...
随机推荐
- iOS开发中遇到的bug
报错:The operation couldn’t be completed. (LaunchServicesError error 0.) 解决办法:重置模拟器
- 《JavaScript权威指南》拾遗(上)
一.语言基础 1.javascript中,只有null和undefined是无法拥有方法的值,它们都没有包装对象.typeof null == ‘object' , typeof un ...
- Web性能优化方案
第一章 打开网站慢现状分析 在公司访问部署在IDC机房的VIP网站时会感觉很慢.是什么原因造成的?为了缩短页面的响应时间,改进我们的用户体验,我们需要知道用户的时间花在等待什么东西上. 可以跟踪一下我 ...
- django-celery提供给顾客使用实例
导入数据库 from djcelery import models as celery_models celery_models.PeriodicTask.objects.create(...) ...
- android:background="@drawable/home_tab_bg"
android:background="@drawable/home_tab_bg" home_tab_bg/xml: <bitmap xmlns:android=" ...
- 剖析MFC六大关键技术(五六)--消息映射与命令传递
说到消息,在MFC中,“最熟悉的神秘”可算是消息映射,那是我们刚开始接触MFC时就要面对的东西.有过SDK编程经验的朋友转到MFC编程的时候,一下子觉得什么都变了样.特别是窗口消息及对消息的处理跟以前 ...
- BZOJ 1610: [Usaco2008 Feb]Line连线游戏
1610: [Usaco2008 Feb]Line连线游戏 Description Farmer John最近发明了一个游戏,来考验自命不凡的贝茜.游戏开始的时 候,FJ会给贝茜一块画着N (2 &l ...
- CUDA samples 2.3节 用CUDA示例来创建CUDA项目
2.3.1. Creating CUDA Projects for Windows 略 2.3.2 Creating CUDA Projects for Linux 默认的samples的安装路径 ...
- SQL Server SQL高级查询语句小结(转)
--select select * from student; --all 查询所有 select all sex from student; --distinct 过滤重复 select disti ...
- 【转】Android数字证书
Android数字证书的作用是非常重要的.Android操作系统每一个应用程序的安装都需要经过这一数字证书的签名. Android手机操作系统作为一款比较流行的开源系统在手机领域占据着举足轻重的地位. ...