使用C++中list容器时必须包含
#include <list>
using namespace std;
list基本概念
list链表是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的;
链表由一系列结点组成,结点由数据域和指针域组成;
由于链表的存储方式并不是连续的内存空间,因此链表list中的迭代器只支持前移和后移,属于双向迭代器;
list的优点:
采用动态存储分配,不会造成内存浪费和溢出
链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素
list的缺点:
空间(指针域)和时间(遍历)额外耗费较大
list构造函数
①list<T> l;
采用模板类实现,默认构造函数
②list(begin,end);
构造函数将[begin,end)区间中的元素拷贝给本身
③list(n,elem);
构造函数将n个elem拷贝给本身
④list(const list &l);
拷贝构造函数
void test() {
list<int> l; //默认构造
list<int> l1(5, 2); //将5个2拷贝给容器l1
list<int> l2(l1.begin(), l1.end()); //区间构造
list<int> l3(l1); //拷贝构造
}
list赋值和交换
①assign(begin,end);
将[begin,end)区间中的数据拷贝赋值给本身
②assign(n,elem);
将n个elem拷贝赋值给本身
③list& operator=(const list &l);
重载=操作符
④swap(l);
将容器l中的元素与当前容器的元素进行互换
void test() {
list<int> l; //默认构造
l.push_back(1); //向容器尾部插入数据
l.push_back(2);
l.push_back(3);
l.push_back(4);
l.push_back(5);
list<int> l1;
l1.assign(l.begin(), l.end()); //将容器l从头到尾的数据拷贝给容器l1
list<int> l2(9, 2); //将9个2拷贝赋值给容器l2
list<int> l3;
l3 = l; //重载=操作符
l3.swap(l2); //交换两个容器中的元素
}
list大小操作
①size();
返回容器中元素的个数
②empty();
判断容器是否为空
③resize(num);
重新设定容器长度为num,若容器变长,新位置以默认值(0)填充;若变短,删除末尾超出容器长度的元素
④resize(num,elem);
重新设定容器长度为num,若容器变长,新位置以elem填充;若变短,删除末尾超出容器长度的元素
void test() {
list<int> l;
l.push_back(1);
l.push_back(2);
l.push_back(3);
l.push_back(4);
l.push_back(5);
if (l.empty()) { //判断容器是否为空
cout << "l为空" << endl;
}
else {
cout << "l不为空" << endl;
cout << "l的元素个数为:" << l.size() << endl;
}
//l.resize(10);
l.resize(10,8);
l.resize(2);
}
list插入和删除
①push_back(elem);
在容器尾部插入元素elem
②push_front(elem);
在容器头部插入元素elem
③pop_back();
删除容器中最后一个元素
④pop_front();
删除容器中第一个元素
⑤insert(pos,elem);
在迭代器指向的pos位置插入元素elem的拷贝
⑥insert(pos,n,elem);
在迭代器指向的pos位置插入n个elem
⑦insert(pos,begin,end);
在迭代器指向的pos位置插入[begin,end)区间的数据
⑧erase(begin,end);
删除[begin,end)区间的数据
⑨erase(pos);
删除迭代器指向的pos位置的元素
⑩remove(elem);
删除容器中所有与elem值匹配的元素
⑪unique();
删除重复的元素
⑫clear();
清空容器中的所有数据
void test() {
list<int> l;
l.push_back(1); //尾部插入元素
l.push_back(2);
l.push_back(3);
l.push_back(4);
l.push_front(5); //头部插入元素
l.push_front(6);
l.push_front(7);
l.push_front(8); //8 7 6 5 1 2 3 4
l.pop_back(); //删除尾部数据 8 7 6 5 1 2 3
l.pop_front(); //删除头部数据 7 6 5 1 2 3
l.insert(l.begin(), 10); //迭代器指向容器头部,在此位置插入元素10 10 7 6 5 1 2 3
list<int>::iterator it = l.begin();
l.insert(++it, 3, 11); //迭代器指向容器头部的下一个元素位置,在此位置插入3个11 10 11 11 11 7 6 5 1 2 3
l.erase(l.begin()); //迭代器指向容器头部,删除迭代器指向的元素 11 11 11 7 6 5 1 2 3
l.unique(); //删除重复的元素,同一个元素只留下一个 11 7 6 5 1 2 3
l.push_back(11);
l.push_back(11);
l.push_back(11); 11 7 6 5 1 2 3 11 11 11
l.remove(11); //删除容器中所有的11 7 6 5 1 2 3
l.clear(); //清空容器
}
list执行插入和删除操作不会造成原有list迭代器失效
list数据存取
①front();
返回容器中的第一个元素
②back();
返回容器中的最后一个元素
void test() {
list<int> l;
l.push_back(1);
l.push_back(2);
l.push_back(3);
l.push_back(4);
l.push_back(5);
cout << "容器l的第一个元素是:" << l.front() << endl; //返回1
cout << "容器l的最后一个元素是:" << l.back() << endl; //返回5
}
不可以用[]和at方式访问list容器中的元素,因为list的本质是链表,存储空间不连续,迭代器也不支持随机访问。
list反转和排序
①reverse();
反转链表
②sort();
链表排序
void printList(const list<int> &l) { //打印容器中的元素
for (list<int>::const_iterator it = l.begin(); it != l.end(); it++) { //迭代器可以自增自减
cout << *it << " ";
}
cout << endl;
}
void test1() {
list<int> l1;
l1.push_back(2);
l1.push_back(7);
l1.push_back(5);
l1.push_back(1);
l1.push_back(9);
printList(l1); //打印结果为:2 7 5 1 9
l1.reverse(); //反转容器中的元素
printList(l1); //打印结果为:9 1 5 7 2
l1.sort(); //对容器中的元素进行排序
printList(l1); //打印结果为:1 2 5 7 9
}
所有不支持迭代器随机访问的容器,都不可以用标准算法,容器内部会提供对应的算法。