list容器是一个双向链表容器,可以高效地进行插入删除元素,但是不能随机存取元素(不支持at()和[]操作符)。
一、list容器的对象构造方法
list对象采用模板类的默认构造形式
例如list<T> lst;
#include<iostream>
#include<list>
using namespace std;
int main()
{
int arr[]={0,1,2,3,4};
list<int> lstInt;
list<float> lstFloat;
list<string> listString;
list<int>::iterator t1;
list<int>::iterator t2;
lstInt.assign(arr,arr+5);
lstInt.push_back(5);//在容器尾部插入元素
lstInt.push_back(5);//在容器尾部删除元素
lstInt.pop_back();
lstInt.push_front(0);//在容器头部插入元素
lstInt.push_front(0);
lstInt.pop_front();//在容器头部删除元素
t1=lstInt.begin();
t2=lstInt.end();
// 正确写法
for(;t1!=t2;t1++)
{
cout<<*t1;
}
cout<<endl;
// 错误写法
// for(;t1<t2;t1++)
// {
// cout<<*t1;
// }
// cout<<endl;
//输出:0012345
return 0;
}
list对象的带参构造方式
list<T> lst(beg,end);该构造函数将区间[beg,end)中的元素拷贝给本身。
beg,end是数组元素的地址。
list<T> list(n,elem);该构造函数将n个elem拷贝给本身。
list<T> lst1(lst2);拷贝构造函数
#include<iostream>
#include<list>
using namespace std;
int main()
{
int arr[]={0,1,2,3,4};
list<int>::iterator t;
//1、list对象带参数构造
//正确写法
list<int> lst1(arr,arr+5); //建立一个存放int的list容器,初始为0,1,2,3,4
list<int> lst2(lst1.begin(),lst1.end()); //建立一个存放int的list容器,初始为0,1,2,3,4
list<int> lst3(3,100);
list<int> lst4(lst1);
for(t=lst1.begin();t!=lst1.end();t++)
{
cout<<*t<<" ";
}
cout<<endl;
for(t=lst2.begin();t!=lst2.end();t++)
{
cout<<*t<<" ";
}
cout<<endl;
for(t=lst3.begin();t!=lst3.end();t++)
{
cout<<*t<<" ";
}
cout<<endl;
for(t=lst4.begin();t!=lst4.end();t++)
{
cout<<*t<<" ";
}
cout<<endl;
//输出
//0 1 2 3 4
//0 1 2 3 4
//100 100 100
//0 1 2 3 4
return 0;
}
二、list与迭代器
list容器的迭代器是双向迭代器。
list.begin();返回容器第一个元素的迭代器。
list.end();返回容器最后一个元素之后的迭代器。
list.rbegin();返回容器倒数第一个元素的迭代器。
list.rend();返回容器倒数最后一个元素后面的迭代器。
#include<iostream>
#include<list>
using namespace std;
int main()
{
int arr[]={0,1,2,3,4};
list<int> lstInt;
list<int>::iterator t1;
list<int>::iterator t2;
lstInt.assign(arr,arr+5);
t1=lstInt.begin();
t2=lstInt.end();
// 正确写法
for(;t1!=t2;t1++)
{
cout<<*t1;
}
cout<<endl;
// 错误写法
// for(;t1<t2;t1++)
// {
// cout<<*t1;
// }
// cout<<endl;
//输出:01234
return 0;
}
三、list容器的赋值
1、list.assign(beg,end); 将区间[beg,end)中的元素拷贝给本身。
2、list.assign(n,elem);将n个elem拷贝给本身。
3、list& operator=(const list &vec);重载等号操作符。
4、list.swap(vec);将vec与本身的元素交换。
#include<iostream>
#include<list>
using namespace std;
int main()
{
int arr[]={0,1,2,3,4};
list<int>::iterator t;
list<int> lst1;
list<int> lst2;
list<int> lst3;
lst1.assign(arr,arr+5);
lst2.assign(3,100);
lst3=lst1;
lst2.swap(lst1);
for(t=lst1.begin();t!=lst1.end();t++)
{
cout<<*t<<" ";
}
cout<<endl;
for(t=lst2.begin();t!=lst2.end();t++)
{
cout<<*t<<" ";
}
cout<<endl;
for(t=lst2.begin();t!=lst2.end();t++)
{
cout<<*t<<" ";
}
cout<<endl;
//输出:
//100 100 100
//0 1 2 3 4
//0 1 2 3 4
return ;
}
四、list容器的大小
list.size();返回容器中元素的个数
list.empty();判断容器是否为空
list.resize(num);重新指定容器长度,若比之前的长度长,超出部分填充默认值,若比之前的长度短,删除超出部分元素。
list.resize(num,elem);重新指定容器长度,若比之前的长度长,超出部分填充指定值,若比之前的长度短,删除超出部分元素。
五、list容器元素的插入
list.insert(pos,elem);在pos位置插入一个elem元素,返回新元素的位置(迭代器类型)
list.insert(pos,n, elem);在pos位置插入n个elem元素,无返回值
list.insert(pos,beg, end);在pos位置插入[beg,end)区间的数据,无返回值。
六、list容器的删除
1、list.clear();移除容器的所有数据
2、list.erase(beg,end);删除[beg,end)区间的数据,返回下一个数据的位置。
3、list.erase(pos);删除pos位置的元素,返回下一个数据的位置。
4、list.remove(elem);删除容器里所有值为elem的元素。
#include<iostream>
#include<list>
using namespace std;
int main()
{
int arr[]={0,1,2,3,4};
list<int> lstInt;
list<int>::iterator t1;
list<int>::iterator t2;
list<int>::iterator t3;
lstInt.assign(arr,arr+5);
t1=lstInt.begin();
for(;t1!=lstInt.end();t1++)
{
cout<<*t1;
}
cout<<endl;
//01234
lstInt.clear();
lstInt.push_front(5);
lstInt.push_front(6);
lstInt.push_front(7);
lstInt.push_front(8);
for(t1=lstInt.begin();t1!=lstInt.end();t1++)
{
cout<<*t1;
}
cout<<endl;
//8765
t2=++lstInt.begin();
t3=++lstInt.begin();
++t3;
++t3;
lstInt.erase(t2,t3);
for(t1=lstInt.begin();t1!=lstInt.end();t1++)
{
cout<<*t1;
}
cout<<endl;
//85
lstInt.push_front(5);
lstInt.push_front(6);
lstInt.push_front(7);
lstInt.push_front(8);
lstInt.remove(5);
for(t1=lstInt.begin();t1!=lstInt.end();t1++)
{
cout<<*t1;
}
cout<<endl;
//8768
//输出
//01234
//8765
//85
//8768
return 0;
}
七、其他
lst.reverse();反转列表
#include<iostream>
#include<list>
using namespace std;
int main()
{
int arr[]={0,1,2,3,4};
list<int> lstInt;
list<int>::iterator t1;
list<int>::iterator t2;
lstInt.assign(arr,arr+5);
lstInt.reverse();
t1=lstInt.begin();
t2=lstInt.end();
for(;t1!=t2;t1++)
{
cout<<*t1;
}
cout<<endl;
// 输出:43210
return 0;
}
2、删除结点导致迭代器失效
#include<iostream>
#include<list>
using namespace std;
int main()
{
int arr[]={0,1,2,3,4,4,4,4,4,4,4,5,5,6,6};
list<int> lstInt;
list<int>::iterator t1;
list<int>::iterator t2;
lstInt.assign(arr,arr+15);
t1=lstInt.begin();
t2=lstInt.end();
//因为list容器使用不连续分配的内存,并且它的erase方法会返回下一个有效的迭代器,所有遍历删除结点可以有以下方式:
//方法1
for(;t1!=t2;)
{
if(*t1==4)
{
t1=lstInt.erase(t1);
}
else
{
t1++;
}
}
//方法2
for(;t1!=t2;t1++)
{
if(*t1==4)
{
lstInt.erase(t1);
}
}
t1=lstInt.begin();
t2=lstInt.end();
for(;t1!=t2;t1++)
{
cout<<*t1<<" ";
}
cout<<endl;
//输出:0 1 2 3 5 5 6 6
return 0;
}