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 < ...
随机推荐
- 【已解决】谁动了我的CurrentPrincipal?求助我在给Artech的wcf petshop增加授权机制的时候遇到的问题。
这个问题已解决,是绑定设置的问题,主要还是因为我自己没有深入理解WCF绑定的安全机制.在这篇博客里面我来说说怎么解决的. 下载了Artech的wcf petshop源码(博文链接)并调试运行成功后,打 ...
- 用户登录session_id观看
通过使用浏览器firefox或者google看cookie id, 这样就知道登录状态怎么样了
- 【转】Ubuntu下deb包的安装方法
[转]Ubuntu下deb包的安装方法 deb是debian linus的安装格式,跟red hat的rpm非常相似,最基本的安装命令是:dpkg -i file.deb dpkg 是Debian P ...
- 解决虚拟内存不够导致Eclipse is not responding
安装目录下eclipse.ini中: 修改参数至必要大小. e.g. -vmargs-Djava.net.preferIPv4Stack=true-Dosgi.requiredJavaVersion= ...
- php随笔8-thinkphp OA系统 客户管理
Action: CustomerinfosAction.class.php <?php /* * 客户信息 控制器 * @author lifu <504861378@qq.com> ...
- python3.4.3如何获取文件的路径
#coding:utf-8from tkinter import *from tkinter import filedialogroot = Tk()root.filename = filedialo ...
- dubbo 服务化
当网站变大后,不可避免的需要拆分应用进行服务化,以提高开发效率,调优性能,节省关键竞争资源等. 当服务越来越多时,服务的URL地址信息就会爆炸式增长,配置管理变得非常困难,F5硬件负载均衡器的单点压力 ...
- kinect for windows - 环境搭建
我是在虚拟机上搭建的开发环境,需要准备如下软件: 1)vmware workstation 10.0.2 (可以去官网下载,key就自己百度吧) 2)win7 32位(一定是32位的) 3)vs201 ...
- 基于visual Studio2013解决C语言竞赛题之0408素数
题目 解决代码及点评 判断一个数是不是素数的方法,一般是看n是不是能被n以内的某个整数(1除外)整除 为了提高效率,这个整数范围一般缩小到n的平方根 如果在这个范围内的整数都不能整除,那么 ...
- 《Clean Code》重点内容总结
读书笔记请见Github博客:http://wuxichen.github.io/Myblog/reading/2014/10/06/CleanCode.html