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. 类似jquery的一个demo

    通过以下的demo,可以大体知道jquery的一些组织结构以及一些实现方法. 实际上jquery就是一个全局变量,只是在这个变量上添加了各种属性和方法. 首先我们要理解什么是匿名函数自执行,简单点就是 ...

  2. Visual C++ 6.0编程环境的使用

    1.1 编制并运行程序的四部曲 (1)编辑(把程序代码输入,交给计算机). (2)编译(成目标程序文件.obj).编译就是把高级语言变成计算机可以识别的2进制语言,计算机只认识1和0,编译程序把人们熟 ...

  3. (IOS)多线程开发

    一.线程的使用 以向网络请求一张图片为例 -(void)downURL:(NSURL *)aURL { NSData *d = [NSData dataWithContentsOfURL:aURL]; ...

  4. 文字适应DIV

    今天突然碰到了一个奇怪的问题  那就是对于纯数字和英文字母  文字多了会超出div  且即使是设置了height:auto overflow-y:auto 也不管用 只是在x轴上出现滚动条   不论用 ...

  5. poj3308Paratroopers(最小割)

    题目请戳这里 题目大意:给一个n*m的矩阵,给一些点(ri,ci)表示该点在第ri行第ci列.现在要覆盖所有的点,已知覆盖第i行代价为Ri,覆盖第j列代价为Cj.总代价是累乘的,求最小总代价能覆盖所有 ...

  6. 基于visual Studio2013解决C语言竞赛题之0303最大数

     题目 解决代码及点评 这道题考察对条件分支和赋值的灵活应用 正常思维 如果 a>b and a>c 那么a最大 如果b>c and b>a 那么b最大 如果c>a ...

  7. java.lang.Math类,方法学习笔记

    /**java.lang 包中的Math 类提供有常量 * 并包含有用于执行基本数学运算的 * 方法,如初等指数.对数.平方根 * 用于进行更高级的数学运算.由于 * 在Math 类的方法都是静态的, ...

  8. zoj p3780 Paint the Grid Again

    地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5267 题意:Leo 有一个N*N 的格子,他又有一把魔法刷,这个刷子能把 ...

  9. SeekBar 样式设置

    1 SeekBar简介 SeekBar是进度条.我们使用进度条时,可以使用系统默认的进度条:也可以自定义进度条的图片和滑块图片等. 2 SeekBar示例 创建一个activity,包含2个SeekB ...

  10. cocos2d-x 之Scene和Layer

    ***************************************转载请注明出处:http://blog.csdn.net/lttree************************** ...