list是一个双向链表容器,可高效地进行插入删除元素。
他与vector和deque有着很大的区别,区别就体现在存储方式上!
vector是单端数组,deque是双端数组。
vector与deque的存储都是连续的,而list是不连续的存储!
list是通过指针方式与自己的上一个或者下一个元素连接在一起,就好比如链条一样。
如图:
而如果你想在中间某个位置插入元素的话,list会将指针指向那个元素,从而无需移动内存,提高效率!
如图:
list容器和vector、deque容器都是大同小异的,很多函数用法都是一样的!
list 特点:
- list不可以随机存取元素,所以不支持at.(position)函数与[]操作符。可以对其迭代器执行++,但是不能这样操作迭代器:it+3
- 使用时包含 头文件
#include <list>
定义
1. 无参数
list<int> list1;
list<double> list2;
list<Student> list3;
注意:尖括号内还可以设置指针类型或自定义类型。
2. 带参数
list<int> list4(5); // 定义时分配五个元素的大小内存给容器,并用0赋值
list<int> list5(10, 2); // 定义时将10个2赋值给容器
list<int> list6(list3.begin(), list3.end()); // 定义时将list5容器的全部元素赋值给list6
// 删除第一个元素
list1.pop_front();
// 删除最后一个元素
list1.pop_back();
// 头部增加
list1.push_front(9);
// 尾部增加
list1.push_back(5);
// 获取第一个元素
int Front = list1.front();
// 获取最后一个元素
int Back = list1.back();
// 对第一个元素赋值
list1.front() = 8;
// 对最后一个元素赋值
list1.back() = 8;
// 返回第一个元素的迭代器
list1.begin();
// 返回最后一个元素的下一个位置的迭代器
list1.end();
// 返回容器中倒数第一个元素的迭代器
list1.rbegin();
// 返回容器中倒数最后一个元素之后的迭代器
list1.rend();
// 返回容器中第一个元素的常量迭代器
list1.cbegin();
// 返回容器中最后一个元素之后的常量迭代器
list1.cend();
// 使用迭代器将list1的值全部赋值给list2
list2.assign(list1.begin(), list1.end());
// 使用前置++和前置–赋值(不能做 +1 操作
list2.assign(++list1.begin(), --list1.end());
// 将10个5赋值给list3
list3.assign(10, 5);
// 使用赋值运算符据重载赋值
list4 = list3;
// 交换两个容器的元素
list1.swap(list4);
// 返回容器中元素的个数
list1.size();
// 判断容器是否为空
list1.empty();
// 重新指定容器的长度,若容器变长,则以默认值0填充新的位置;如果容器变短,则末尾超出容器的长度的元素被删除
list1.resize(10);
// 重新指定容器的长度,若容器变长,则以5填充新的位置;如果容器变短,则末尾超出容器的长度的元素被删除
list1.resize(15, 5);
// 在开头位置插入一个666
list2.insert(list2.begin(), 666);
// 在第二个位置开始插入5个888
list2.insert(++list2.begin(), 5, 888);
// 在开头位置插入list1的所有元素
list2.insert(list2.begin(), list1.begin(), list1.end());
// 在最后面插入3个777
list2.insert(list2.end(), 3, 777);
// 这条表达式可以在任何位置插入元素,i是需要插入元素的位置
list<int>::iterator it = list2.begin();
for (int i=0; it != list2.end(); it++, i++) {
if (i == 3) {
list2.insert(it, list1.begin(), list1.end());
}
}
// for循环逐个遍历,判断需要删除的元素
for (list<int>::iterator it = list1.begin(); it != list1.end(); ) {
if (*it == 2) {
it = list1.erase(it);
} else {
it++;
}
}
// 删除所有元素
list1.clear();
// 删除[beg,end)区间的数据,返回下一个数据的位置
// list1.erase(beg, end);
list1.erase(++list1.begin(), --list1.end());
// 删除第二个元素
list1.erase(list1.begin());
// 删除容器中所有与参数匹配的元素
list1.remove(3);
// 将容器中的元素反序
list1.reverse();
例如:
list<int> list1;
list1.push_back(1);
list1.push_back(2);
// 反序
list1.reverse();
list<int>::iterator it = list1.begin();
for (; it != list1.end(); it++) {
cout << *it << " "; // 输出值为 2 1
}
cout << endl;
测试代码:
#include <iostream>
#include <Windows.h>
#include <list>
using namespace std;
// 定义
void test1(void) {
list<int> list1;
list<double> list2;
// 带参的
list<int> list3(10, 2);
list<int> list4(list3.begin(), list3.end());
list<int>::iterator it = list4.begin();
for (; it != list4.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
// 头尾/插入/删除
void test2(void) {
list<int> list1;
list1.push_back(1);
list1.push_back(2);
list1.push_back(3);
list1.push_back(4);
list1.push_back(5);
// 删除第一个元素
list1.pop_front();
// 删除最后一个元素
list1.pop_back();
// 头部增加
list1.push_front(9);
// 尾部增加
list1.push_back(9);
list<int>::iterator it = list1.begin();
for (; it != list1.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
// 数据存储
void test3(void) {
list<int> list1;
list1.push_back(1);
list1.push_back(2);
list1.push_back(3);
list1.push_back(4);
list1.push_back(5);
// 获取第一个元素
int Front = list1.front();
// 获取最后一个元素
int Back = list1.back();
// 对第一个元素赋值
list1.front() = 8;
// 对最后一个元素赋值
list1.back() = 8;
list<int>::iterator it = list1.begin();
for (; it != list1.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
// 迭代器
void test4(void) {
list<int> list1;
list1.push_back(1);
list1.push_back(2);
list1.push_back(3);
list1.push_back(4);
list1.push_back(5);
// 返回第一个元素的迭代器
list1.begin();
// 返回最后一个元素的下一个位置的迭代器
list1.end();
// 返回容器中倒数第一个元素的迭代器
list1.rbegin();
// 返回容器中倒数最后一个元素之后的迭代器
list1.rend();
// 返回容器中第一个元素的常量迭代器
list1.cbegin();
// 返回容器中最后一个元素之后的常量迭代器
list1.cend();
}
// 赋值
void test5(void) {
list<int> list1, list2, list3, list4;
list1.push_back(1);
list1.push_back(2);
list1.push_back(3);
list1.push_back(4);
list1.push_back(5);
// 使用迭代器将list1的值全部赋值给list2
list2.assign(list1.begin(), list1.end());
// 使用前置++和前置--赋值(不能做 +1 操作)
list2.assign(++list1.begin(), --list1.end());
// 将10个5赋值给list3
list3.assign(10, 5);
// 使用赋值运算符据重载赋值
list4 = list3;
// 交换两个容器的元素
list1.swap(list4);
list<int>::iterator it = list1.begin();
for (; it != list1.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
// list的大小
void test6(void) {
list<int> list1;
list1.push_back(1);
list1.push_back(2);
list1.push_back(3);
list1.push_back(4);
list1.push_back(5);
// 返回容器中元素的个数
list1.size();
// 判断容器是否为空
list1.empty();
// 重新指定容器的长度,若容器变长,则以默认值0填充新的位置;如果容器变短,则末尾超出容器的长度的元素被删除
list1.resize(10);
// 重新指定容器的长度,若容器变长,则以5填充新的位置;如果容器变短,则末尾超出容器的长度的元素被删除
list1.resize(15, 5);
list<int>::iterator it = list1.begin();
for (; it != list1.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
// list 中间插入
void test7(void) {
list<int> list1;
list<int> list2(5);
list1.push_back(1);
list1.push_back(2);
list1.push_back(3);
list1.push_back(4);
list1.push_back(5);
// 在开头位置插入一个666
list2.insert(list2.begin(), 666); // 666 0 0 0 0 0
// 在第二个位置开始插入5个888
list2.insert(++list2.begin(), 5, 888); // 666 888 888 888 888 888 0 0 0 0 0
// 在开头位置插入list1的所有元素
list2.insert(list2.begin(), list1.begin(), list1.end()); // 1 2 3 4 5 666 888 888 888 888 888 0 0 0 0 0
// 这条表达式可以在任何位置插入元素,i是需要插入元素的位置
list<int>::iterator it = list2.begin();
for (int i=0; it != list2.end(); it++, i++) {
if (i == 3) {
list2.insert(it, list1.begin(), list1.end()); // // 1 2 3 1 2 3 4 5 4 5 666 888 888 888 888 888 0 0 0 0 0
}
}
it = list2.begin();
for (; it != list2.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
// list的删除
void test8(void) {
list<int> list1;
list1.push_back(1);
list1.push_back(2);
list1.push_back(3);
list1.push_back(4);
list1.push_back(5);
// 删除所有元素
list1.clear();
//list1.erase(beg, end); // 删除[beg,end)区间的数据,返回下一个数据的位置
list1.erase(++list1.begin(), --list1.end());
// 删除第二个元素
list1.erase(list1.begin());
// for循环逐个遍历,判断需要删除的元素
for (list<int>::iterator it = list1.begin(); it != list1.end(); ) {
if (*it == 2) {
it = list1.erase(it);
} else {
it++;
}
}
// 删除容器中所有与参数匹配的元素
list1.remove(3);
}
// list的反序函数
void test9(void) {
list<int> list1;
list1.push_back(1);
list1.push_back(2);
list1.push_back(3);
list1.push_back(4);
list1.push_back(5);
// 将容器中的元素反序
list1.reverse();
list<int>::iterator it = list1.begin();
for (; it != list1.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
int main(void) {
//test1();
//test2();
//test3();
//test4();
//test5();
//test6();
//test7();
//test8();
//test9();
system("pause");
return 0;
}
总结:
list和vec和deque这三个容器都是差不多的,只要会使用一个,那么其他两个都会了,其语法差不多。list具有更好的效率,在实际开发中也比较常用!