国外photoshop素材网站,南京网站推广费用,wordpress文章缩略图,WordPress信息收集一、前言 本次博客主要讲解 list 容器的基本操作、常用接口做一个系统的整理#xff0c;结合具体案例熟悉自定义内部排序方法的使用。如有任何错误#xff0c;欢迎在评论区指出#xff0c;我会积极改正。
二、什么是list
list是C的一个序列容器#xff0c;插入和删除元素…一、前言 本次博客主要讲解 list 容器的基本操作、常用接口做一个系统的整理结合具体案例熟悉自定义内部排序方法的使用。如有任何错误欢迎在评论区指出我会积极改正。
二、什么是list
list是C的一个序列容器插入和删除元素的效率较高时间复杂度为常数级别list容器的底层数据结构为带头双向循环链表这使得 list的元素可以存储在非相邻的内存中在list内部不同元素之间通过指向前一个元素的指针以及指向后一个元素的指针相关联。它的数据由若干个节点构成每一个节点都包括一个信息块即实际存储的数据、一个前驱指针和一个后驱指针可以向前也可以向后进行访问但不能随机访问。列表的定义在头文件list中。list 容器与其他序列容器如vector deque array相比由于其底层数据结构为带头双向循环链表因此 list 在插入删除元素方面很有优势在列表的任意位置进行插入和删除操作的时间复杂度为O(1)。但不能直接通过位置(下标)来直接访问元素。想要访问list的某个元素必须从list的一端或已知位置迭代到该元素。另外list还需要额外的存储空间来储存前一个元素和后一个元素的链接信息。
1.list的存储结构 list 容器底层为带头双向循环链表带头双向循环链表每个节点包含指向前驱节点的pre指针指向后继节点的next指针以及节点的数据。list存储结构如下图所示 哨兵节点表示链表的第一个元素节点且不保存任何数据。
2.list 容器的优点
1高效的插入和删除由于std::list是基于带头双向循环链表实现的插入和删除操作在任意位置都具有常数时间复杂度O(1)不需要移动其他元素。这使得std::list在需要频繁插入和删除元素的场景下非常高效。2稳定的迭代器在std::list中进行插入和删除操作不会使得迭代器失效。这意味着在插入或删除元素后仍然可以继续使用之前获取的迭代器进行遍历和操作。3动态内存管理std::list可以动态调整大小根据需要分配和释放内存。这使得std::list能够有效地处理大量元素的情况而不会浪费过多的内存空间。
3.list容器的缺点
低效的随机访问由于std::list的存储结构是带头双向循环链表访问元素时需要从头或尾开始遍历链表因此在列表中进行随机访问的效率较低。获取特定位置的元素需要遍历链表时间复杂度为O(n)其中n是元素的总数量。占用额外内存相较于其他容器std::list在存储上需要额外的指针来维护链表结构因此在存储大量元素时它可能占用更多的内存空间。迭代器不支持指针算术std::list的迭代器不支持指针算术运算无法像指针那样直接进行加减操作这限制了一些操作的灵活性。
头文件
list是C 标准模板库的一部分因此想要使用list需要在程序中包含头文件 list
#includelist三、list 容器的定义
单独定义一个 list
list typename name; 这里的typename可以是任何基本类型例如int、double、char、结构体等也可以是STL标准容器例如string、set、queue、vector等。 注意使用前必须加上头文件#include list 四、list 容器常用接口的使用
4.1 list 的常见构造初始化
在 C 中std::list 是一个双向链表容器提供了一些灵活的初始化方式。以下是 std::list 的常见构造初始化方法
1默认构造函数
创建一个空list,不包含任何元素。
#include iostream
#include list
using namespace std;int main(){listint str_a; //list定义的int类型的列表return 0;
}
2使用指定数量的元素构造
使用 n 个元素初始化 list每个元素的值为默认值例如对于 int默认值为 0。
#include iostream
#include list
using namespace std;int main(){listint myList(5); // 列表包含 5 个元素默认值为 0return 0;
}
也可以指定一个初始值 val为所有元素赋相同的值。
#include iostream
#include list
using namespace std;int main(){listint myList(5, 10); // 列表包含 5 个元素每个元素的值为 10return 0;
}
3使用初始化列表构造
使用花括号 {} 来初始化 list指定初始元素的值。
#include iostream
#include list
using namespace std;int main(){listint myList {1,2,3,4,5}; //列表包含5个元素依次为1,2,3,4,5return 0;
}
4拷贝构造函数
使用另一个 list 来初始化新的 list会创建一个原列表的副本。
#include iostream
#include list
using namespace std;int main(){listint originalList {1, 2, 3};listint copiedList(originalList); // 使用 originalList 初始化 copiedList列表包含 3 个元素依次为 1, 2, 3return 0;
}
5移动构造函数
使用 move 将一个临时 list 资源转移到新 list 中从而避免拷贝开销。
#include iostream
#include list
using namespace std;int main(){listint originalList {1, 2, 3};listint movedList(move(originalList)); // originalList 变为空movedList 拥有原始数据return 0;
}
6范围构造函数
使用迭代器范围 [first, last) 初始化 list可以将其他容器的部分或全部内容拷贝到 list 中。
#include iostream
#include list
#include vectorusing namespace std;int main(){vectorint vec {1, 2, 3, 4, 5};listint myList(vec.begin(), vec.end()); // 使用 vector 的元素初始化 listreturn 0;
}
7使用 assign 赋值
虽然这不是构造函数但 assign 可以在声明后直接赋值初始化。
#include iostream
#include list
#include vectorusing namespace std;int main(){listint myList;myList.assign(5, 10); // 列表包含 5 个元素每个元素的值为 10return 0;
}
4.2 list 的遍历及迭代器的操作
接口名称接口说明 迭代器⭐ begin() end() 或者 rbegin() rend()范围forC11支持更简单的for的新遍历方式底层还是借用迭代器实现
注意遍历链表-------只能用**迭代器**和**范围for**
begin与end为正向迭代器对迭代器执行操作迭代器向后移动rbegin(end)与rend(begin)为反向迭代器对迭代器执行操作迭代器向前移动
迭代器
接口名称接口说明begin()⭐返回第一个元素的迭代器end()⭐返回最后一个元素下一个位置的迭代器rbegin()返回最后一个元素的迭代器rend()返回第一个元素的前一个位置额迭代器 1. 使用迭代器遍历
通过 begin() 和 end() 获取 list 的起始和终止迭代器使用迭代器遍历 list。
#include iostream
#include list
using namespace std;int main(){listint myList {1,2,3,4,5};// 使用普通迭代器遍历for(listint::iterator it myList.begin(); it ! myList.end(); it){cout *it ;}cout endl; //输出1 2 3 4 5 return 0;
}
注意begin与end为正向迭代器对迭代器执行操作迭代器向后移动 rbegin和rend
通过rbegin函数可以得到容器中最后一个元素的反向迭代器通过rend函数可以得到容器中第一个元素的前一个位置的反向迭代器。
反向迭代器遍历容器
#include iostream
#include list
using namespace std;
int main()
{int array[] { 1,2,3,4,5,6,7,8 };// 用已有的数组 初始化 list 链表listint lt(array, array sizeof(array) / sizeof(array[0]));// 正向迭代器遍历容器listint::reverse_iterator it lt.rbegin();// 开始循环遍历while (it ! lt.rend()){cout *it ; // 8 7 6 5 4 3 2 1it;}cout endl;return 0;
}
注意rbegin(end)与rend(begin)为反向迭代器对迭代器执行操作迭代器向前移动
2使用基于范围的 for 循环C11
在 C11 及以上版本中可以使用基于范围的 for 循环简化遍历过程。
#include iostream
#include listusing namespace std;int main(){listint myList {1,2,3,4,5};for(int value : myList){cout value ;}cout endl; // 输出1 2 3 4 5return 0;
}
4.3 list 容器的常见容量操作
接口名称接口说明empty()判断 list 是否为空size返回容器中有效元素个数resize⭐ 调整容器的有效元素大小(size) clear用于清空容器,清空后容器的size为0, 但是头结点(哨兵位)不会被清除
1empty()
判断 list 是否为空。如果 list 不包含任何元素则返回 true否则返回 false。
#include iostream
#include list
using namespace std;int main(){listint myList;if(myList.empty()) {cout The list is empty. endl;} else{cout The list is not empty. endl;}return 0; // 输出The list is empty.
}
2size()
返回 list 中元素的数量。
#include iostream
#include list
using namespace std;int main()
{listint myList {1,2,3,4,5};cout Size of the list: myList.size()endl; // 输出5return 0;
}
3resize()
调整 list 的大小。如果新大小比当前大小大则会在 list 的末尾添加默认值的元素如果新大小比当前大小小则会移除多余的元素。
#include iostream
#include list
using namespace std;void PrintList(listint l){listint::iterator it l.begin();while(it ! l.end()){cout *it ;it ;}cout endl;
}int main(){listint myList {1,2,3,4,5};// 缩小列表的大小myList.resize(3); // 现在myList只包含1,2,3PrintList(myList);//扩大列表的大小添加默认值0myList.resize(6); // 现在myList包含1,2,3,0,0,0PrintList(myList);return 0;
}
4clear clear 函数用于清空容器,清空后容器的size为0, 但是头结点(哨兵位)不会被清除。
#include iostream
#include list
using namespace std;int main()
{listint lt(5, 2);for (auto e : lt){cout e ;}cout endl; //2 2 2 2 2cout lt.size() endl; //5lt.clear(); //清空容器for (auto e : lt){cout e ;}cout endl; //(无数据)cout lt.size() endl; //0return 0;
}
list 容量的常见访问操作
① front()——访问list头元素
❤front()返回list第一个元素❤
#includeiostream
#includelist
using namespace std;int main(){listint mylist {1,2,3,4,5,6,7,8};cout 初始化后的mylist为 ;for(auto num: mylist){cout num ;}int front mylist.front(); // 1cout \nmylist的头元素为: front;return 0;
} ② back()——访问list尾元素
❤back()返回list第一个元素❤ 示例如下
示例代码
#includeiostream
#includelistusing std::cout;
using std::endl;
using std::list;int main() {listint mylist {1, 2, 3, 4, 5, 6, 7, 8};cout 初始化后的mylist为;for (auto num : mylist) {cout num ;}int front mylist.back(); // 8cout \nmylist的头元素为 front;
}
list 容器的常见修改操作
接口名称接口说明push_front在list首元素前插入值为val的元素pop_front 删除list中第一个元素 push_back在list尾部插入值为val的元素pop_back删除list中最后一个元素insert⭐在list position 位置中插入值为val的元素erase⭐删除list position位置的元素swap交换两个list中的元素
① push_back()——添加元素list尾部) 向list中添加元素使用push_back()方法作用是向list尾部添加一个元素。示例如下 示例代码
#include list
#include iostream
using namespace std;int main(){listint mylist{1,2,3,4};cout 初始化后的mylist为 ;for(auto num:mylist){cout num ;}//在list尾部插入一个元素8mylist.push_back(8);cout \n尾部插入一个元素后的mylist为 ;for(auto num: mylist){cout num ; //1 2 3 4 8}return 0;
}
② pop_back()——移除list元素(尾部)
删除list中的元素使用pop_back()方法作用是删除list尾部的一个元素。示例如下
示例代码
#include list
#include iostreamusing std::cout;
using std::list;
using std::endl;int main() {listint mylist{1, 2, 3, 4};cout 初始化后的mylist为;for (auto num : mylist) {cout num ;}// 删除mydeue尾部一个元素mylist.pop_back();cout \n尾部删除一个元素后的mylist为;for (auto num : mylist) {cout num ; // 1 2 3}
} ③ pop_front()——删除list元素(头部) 删除list中的元素使用pop_front()方法作用是删除list头部的一个元素。示例如下
示例代码
#include list
#include iostreamusing std::cout;
using std::list;
using std::endl;int main() {listint mylist{1, 2, 3, 4};cout 初始化后的mylist为;for (auto num : mylist) {cout num ;}// 删除mydeue头部一个元素mylist.pop_front();cout \n头部删除一个元素后的mylist为;for (auto num : mylist) {cout num ; // 2 3 4}
}
④ push_front()——添加元素list头部) 向list中添加元素使用push_front()方法作用是向list头部添加一个元素。示例如下
示例代码
#include list
#include iostreamusing std::cout;
using std::list;
using std::endl;int main() {listint mylist{1, 2, 3, 4};cout 初始化后的mylist为;for (auto num : mylist) {cout num ;}// 在list头部插入一个元素8mylist.push_front(8);cout \n头部插入一个元素后的mylist为;for (auto num : mylist) {cout num ; // 8 1 2 3 4}
}
⑤ insert()——添加元素任意位置
insert共有三种形式 - insert(iterator, value); - insert(iterator, num, value); - insert(iterator, iterator1, iterator2);
用法一list.insert(iterator,value) 使用insert(iterator,value)方法作用是向iterator迭代器指向元素的前边添加一个元素value并返回一个迭代器指向新插入的元素。 #include iostream
#include list
using namespace std;void PrintList(listint l){for(auto num : l){cout num ;}cout endl;
}int main(){listint mylist{1,2,3,4};cout 初始化后的mylist为;PrintList(mylist);// it 指向mylist的第二个元素listint::iterator it mylist.begin();it ;// 使用insert添加一个元素listint::iterator itnew mylist.insert(it,10);cout \n返回的迭代器指向的元素为: *itnew endl;PrintList(mylist);return 0;
}
用法二list.insert(iterator,num,value)
使用insert(iterator,num,value)方法作用是向iterator迭代器指向元素的前边添加num个元素value并返回一个迭代器指向新插入的第一个元素. #include iostream
#include list
using namespace std;void PrintList(listint l){for(auto num: l){cout num ;}cout endl;
}int main(){listint mylist{1,2,3,4};cout 初始化后的mylist为 ;for(auto num : mylist){cout num ;}// it 指向mylist的第二个元素listint::iterator it mylist.begin();it ;//使用insert添加2个元素value为20mylist.insert(it, 2, 20);PrintList(mylist);return 0;
}
用法三insert(iterator, iterator1, iterator2)
使用insert(iterator, iterator1, iterator2);方法作用是向iterator迭代器指向元素的前边添加[iterator1,iterator2)之间的元素。 示例代码
#include list
#include iostream
using namespace std;void PrintList(listint l)
{for(auto num: l){cout num ;}cout endl;
}int main(){listint mylist{1,2,3,4};cout 初始化后的mylist为 ;// it指向mylist的第二个元素listint::iterator it mylist.begin();it ;//定义一个辅助listlistint list{20,30,40};//it1指向list的第一个元素::listint::iterator it1 list.begin();// it2指向list2的最后一个元素后一个位置::listint::iterator it2 list.end();// 使用insert在2之前添加[it1,it2]之间的元素mylist.insert(it,it1,it2);cout \n使用insert插入元素后;PrintList(mylist);return 0;
}
⑥ erase()——删除元素任意位置
❤erase的作用就是根据传入的迭代器删除list中的元素,参数为一个迭代器只删除迭代器指向的元素参数为两个迭代器删除两个迭代器之间的元素❤ erase 共有 两 种形式 - list.erase(iterator) - list.erase(iterator1,iterator2) 用法一list.erase(iterator)
这种用法会删除迭代器iterator指向的元素。 示例代码
#include list
#include iostream
using namespace std;void PrintList(listint l){for( auto num: l){cout num ;}}int main(){listint mylist{1,2,3,4};cout 初步化后的mylist为;// it指向mylist的第二个元素listint::iterator it mylist.begin();it ;//删除it指向的元素即2并返回一个迭代器指向2之后的元素listint::iterator itnew mylist.erase(it);cout \n删除元素后返回的迭代器itnew指向的元素为 *itnew;cout \n使用erase删除元素后;PrintList(mylist);} 用法二list.erase(iterator1,iterator2)
这种用法会删除迭代器iterator1指向的元素到iterator2指向元素之间的元素包括iterator1指向的元素但不包括iterator2指向的元素即擦除[iterator1,iterator2)。 示例代码
#include iostream
#include list
using namespace std;void PrintList(listint l){for( auto num: l){cout num ;}}int main(){listint mylist{1,2,3,4};cout 初始化后的mylist为;PrintList(mylist);//it1指向mylist的第2个元素listint::iterator it1 mylist.begin();it1 ;// it2指向最后一个元素的最后一个位置listint::iterator it2 mylist.end();// 删除[it1,it2]之间的元素即删除2,3,4mylist.erase(it1,it2);cout \n使用erase删除元素后;PrintList(mylist);return 0;
}
⑦ swap()——交换元素 ❤swap的作用就是交换两个list的元素❤
交换两个list的元素使用 swap()方法 list1.swap(list2),两个list存储的元素类型必须相同元素个数可以不同。示例如下 示例代码
/*交换两个list的元素使用swap()方法list1.swap(list2),两个list存储的元素类型必须相同元素个数可以不同。
*/
#include list
#include iostream
using namespace std;void PrintList(listint l){for( auto num: l){cout num ;}cout endl;}int main(){listint mylist1{1,11,111,1111};listint mylist2{2,22,222};cout 初始化后的mylist1为;PrintList(mylist1);cout 初始化后的mylist2为;PrintList(mylist2);//交换两个列表的元素·mylist1.swap(mylist2);//交换后mylist1为cout 使用swap()交换后mylist1为;PrintList(mylist1);cout 使用swap()交换后mylist1为;PrintList(mylist2);return 0;
}
输出
初始化后的mylist1为1 11 111 1111
初始化后的mylist2为2 22 222
使用swap()交换后mylist1为2 22 222
使用swap()交换后mylist1为1 11 111 1111
list 容器的常见操作函数
函数声明接口说明splice将元素从列表转移到其它列表remove删除具有特定值的元素remove_if删除满足条件的元素unique删除重复值sort容器中的元素排序merge合并排序列表reverse反转元素的顺序
① splice()——从另一个list中移动元素
splice 方法用于将另一个 std::list 的元素插入到当前列表的指定位置。示例如下 splice共有三种形式分别为 splice(iterator_pos, otherList) : 将otherList中的所有元素移动到iterator_pos指向元素之前splice(iterator_pos, otherList, iter1): 从 otherList转移 iter1 指向的元素到当前list。元素被插入到 iterator_pos指向的元素之前。splice(iterator_pos, otherList, iter_start, iter_end) : 从 otherList转移范围 [iter_start, iter_end) 中的元素到 当前列表。元素被插入到 iterator_pos指向的元素之前。 注意
1. splice 操作不会进行元素的复制或移动只是修改指针连接因此效率较高。 2. 在 splice 操作后被移动的元素将不再属于原始列表。 3. splice 操作后原始列表和插入列表的大小会相应改变。 4. 插入操作的时间复杂度为 O(1)
示例代码
#include iostream
#include list
using namespace std;void PrintList(listint l){for( auto num: l){cout num ;}cout endl;}int main(){listint list1{1,2,3,4,5};listint list2{10,20,30};listint list3{1,2,3,4,5};listint list4{10,20,30};listint list5{1,2,3,4,5};listint list6{10,20,30};cout 初始化之后的list1 ;PrintList(list1);/*用法一 : splice(iterator_pos, otherList)*/// 将list2中所有元素插入到list1的第一个位置list1.splice(list1.begin(),list2);// 输出结果cout 转移list2元素到list1之后的list1 ;PrintList(list1);cout 转移list2元素到list1之后的list2 ;PrintList(list2);/*用法二splice(iterator_pos, otherList, iter1)*/auto it list3.begin();//将迭代器向后移动两个位置指向第三个元素advance(it,2);//将list4的第一个元素10插入到list3的第三个位置list3.splice(it,list4,list4.begin());//输出结果cout 转移list4元素到list3之后的list3 ;PrintList(list3);cout 转移list4元素到list3之后的list4 ;PrintList(list4);/*用法三splice(iterator_pos, otherList, iter_start, iter_end)*/auto it2 list5.begin();advance(it2,2);list5.splice(it2,list6,list6.begin(),list6.end());cout 转移list6元素到list5之后的list5 ;PrintList(list5);cout 转移list6元素到list5之后的list6 ;PrintList(list6);return 0;
}
运行结果
初始化之后的list1 1 2 3 4 5
转移list2元素到list1之后的list1 10 20 30 1 2 3 4 5
转移list2元素到list1之后的list2
转移list4元素到list3之后的list3 1 2 10 3 4 5
转移list4元素到list3之后的list4 20 30
转移list6元素到list5之后的list5 1 2 10 20 30 3 4 5
转移list6元素到list5之后的list6
② remove()——移除特定值的元素
std::list 的 remove 方法用于从列表中移除与指定值相等的元素。示例如下
#include iostream
#include listint main() {std::listint mylist {1, 2, 3, 4, 5};// 移除列表中所有值为2的元素mylist.remove(2);std::cout 移除之后的mylist: ;for (const auto element : mylist) {std::cout element ;}std::cout std::endl;return 0;
}
③ remove_if()——移除满足特定标准的元素
使用方式remove_if(func)使用 remove_if 方法可以从 mylist 中移除所有满足 函数func的元素下边的例子中定义了一个函数isEven()判断一个数字是否为偶数。示例如下 示例代码
#include iostream
#include list
using namespace std;bool isEven(int n){return n % 2 0;
}
int main(){listint mylist{1,2,3,4,5};// 一处列表中所有满足 isEven 的元素偶数mylist.remove_if(isEven);cout 移除之后的mylist: ;for(const auto element : mylist){cout element ;}cout endl;return 0;
}输出 移除之后的mylist: 1 3 5 ④ unique()——删除连续的重复元素 unique()方法用于移除链表中相邻且重复的元素仅保留一个副本。示例如下 示例代码
#include iostream
#include list
using namespace std;int main(){listint mylist{1,2,2,3,3,4,5,5,5};cout 初始化后的list为 ;for(auto i: mylist){cout i ;}cout endl;mylist.unique();cout 执行unique后的list为 ;for (auto i: mylist){cout i ;}cout endl;return 0;
}
运行结果
初始化后的list为 1 2 2 3 3 4 5 5 5
执行unique后的list为 1 2 3 4 5
⑤ sort()——对元素进行排序 sort()方法用于对链表中的元素进行排序。默认情况下它按升序对元素进行排序使用元素类型的 运算符进行比较。示例如下 示例代码
#include iostream
#include list
using namespace std;void PrintList(listint l){for( auto num: l){cout num ;}cout endl;
}int main(){listint mylist{5,0,3,2,4,1};cout 初始化后的list为 ;PrintList(mylist);mylist.sort();cout 经过sort排序后的list为;PrintList(mylist);return 0;
}
运行结果
初始化后的list为 5 0 3 2 4 1
经过sort排序后的list为0 1 2 3 4 5
⑥ merge()——合并list 将两个已排序的列表合并成一个有序的列表。merge()方法将另一个列表的元素插入到调用方法的列表中并保持排序顺序。示例如下 注意merge()方法只能用于已排序的list。如果list未排序则合并的结果将是不正确的。
示例代码
#include iostream
#include list
using namespace std;void PrintList(listint l){for( auto num: l){cout num ;}cout endl;
}int main(){listint list1{1,3,5};listint list2{2,4,6};cout 初始化后的list1为 ;PrintList(list1);cout 初始化后的list2为 ;PrintList(list2);//将list2合并到list1中list1.merge(list2);// 输出合并后的列表cout 合并后的list1为 ;PrintList(list1);return 0;
}
运行结果
初始化后的list1为 1 3 5
初始化后的list2为 2 4 6
合并后的list1为 1 2 3 4 5 6 ⑦ reverse()——将该链表的所有元素的顺序反转 【C11】 reverse()方法用于反转链表中元素的顺序即将链表中的第一个元素变为最后一个元素第二个元素变为倒数第二个元素以此类推。示例如下 示例代码
#include iostream
#include listusing namespace std;void PrintList(listint l){for( auto num: l){cout num ;}cout endl;
}int main(){listint mylist{1,2,0,3,4,5};cout 初始化list为;PrintList(mylist);mylist.reverse();cout Reverse后的list为;PrintList(mylist);return 0;
}
代码运行结果
初始化list为1 2 0 3 4 5
Reverse后的list为5 4 3 0 2 1 ⑧ assign()——将值赋给容器
assign()方法用于将链表中的元素替换为新的元素序列。它可以接受不同形式的参数提供了两种重载形式。
第一种形式接受迭代器范围作为参数用于将另一个容器或数组中的元素复制到链表中。它会将链表清空并将指定范围内的元素复制到链表中。void assign(InputIterator first,InputIteratorlast);第二种形式接受一个元素数量和一个值作为参数用于将指定数量的相同值的元素分配给链表。它会将链表清空并将指定数量的元素赋值为指定的值。void assign(size_type count, const T value);
示例代码
#include iostream
#include vector
#include listint main() {std::listint myList;// 使用迭代器范围进行分配std::vectorint numbers {1, 2, 3, 4, 5};myList.assign(numbers.begin(), numbers.end());std::cout 第一次执行assign之后的list为: ;for (auto i : myList) {std::cout i ;}std::cout std::endl;// 使用元素数量和值进行分配myList.assign(3, 100);std::cout 第二次执行assign之后的list为: ;for (auto i : myList) {std::cout i ;}std::cout std::endl;return 0;
}
运行结果:
第一次执行assign之后的list为: 1 2 3 4 5
第二次执行assign之后的list为: 100 100 100
五、vector 与 list 的对比
对比vectorlist底层结构动态顺序表连续空间带头结点的双向循环链表访问支持随机访问首地址下标不能随机访问可通过find查找访问随即元素时间复杂度O(N)插入删除任意位置插入和删除效率低需要搬移元素时间复杂度为O(N)插入时有可能需要增容增容开辟新空间拷贝元素释放旧空间导致效率更低任意位置插入和删除效率高不需要搬移元素时间复杂度为O(1)空间利用率底层为连续空间不容易造成内存碎片空间利用率较高缓存利用率高。可以一次将一个数据附近的空间都加载到缓存不用频繁地从内存读取数据底层节点动态开辟容易造成内存碎片空间利用率低缓存利用率低迭代器原生态指针对指针进行了封装迭代器失效容量相关的操作都有可能导致迭代器失效如插入引起的扩容删除元素等插入元素不会导致迭代器失效删除节点会导致且只影响当前迭代器其他迭代器不受影响使用场景不关心插入和删除效率支持随机访问大量插入和删除操作不关心随机访问的场景