【C++打怪之路Lv10】-- list

简介: 【C++打怪之路Lv10】-- list

什么是list


在C++中,list是一种序列容器,属于标准模板库(STL)的一部分。

它是一个双向链表,可以高效地进行插入和删除操作,尤其是在序列的中间部分

list的特点

  1. 动态数组list是一个动态数组,其长度可以根据需要增长或缩小。
  2. 双向链表:每个节点包含数据和两个指针,分别指向前一个和后一个节点,允许双向遍历。
  3. 插入和删除操作高效:在任何位置插入或删除元素都非常快速,因为不需要移动其他元素。
  4. 没有随机访问list不支持通过索引直接访问元素,访问必须从头开始迭代。
  5. 内存分配:元素可以非连续地存储在内存中,无需连续的内存块。
  6. 迭代器:提供双向迭代器,可以向前和向后遍历。
  7. 常用成员函数:如push_back, push_front, pop_back, pop_front, insert, erase, splice等,用于链表操作。

小结:选择使用list还是其他容器(如vector或deque)取决于具体的应用场景和性能需求。如果应用需要频繁地在序列中间插入或删除元素list是一个很好的选择。

如果需要快速随机访问元素,则vector可能是更好的选择。


list常用的函数接口


构造函数

1)无参构造

list();

创建一个空的list容器,不包含任何元素

2)用n个val值构造

list(size_t n, const value_type& val = value_type());

创建一个包含n个元素的list容器,所有元素都被初始化为val的副本。

如果不提供val参数,则使用默认构造函数初始化元素

3)拷贝构造函数

list(const list& x);

创建一个新的list容器,它是另一个同类型list容器x的副本。

这个构造函数会复制x中的所有元素到新的容器中

4)用迭代器进行初始化构造

1. template <class InputIterator>
2. list(InputIterator first, InputIterator last);

创建一个list容器,并用迭代器范围[first, last)中的元素来初始化它。

这个构造函数可以用来从一个已存在的容器或者迭代器指定的序列中复制元素到新的list容器中。InputIterator可以是任何能够提供输入迭代器功能的迭代器类型

容量操作接口

1)size

size_t size() const;

返回list中实际元素的个数。

这个操作的时间复杂度是常数时间O(1),因为它不需要遍历整个容器来计算元素的数量

2)empty

bool empty() const;

检查list是否为空,即是否不包含任何元素。

如果容器为空,则返回true;否则返回false

这个操作同样具有常数时间复杂度O(1)

3)resize

void resize(size_type n);
void resize(size_type n, const value_type& val);

调整list容器的大小以包含n个元素。

如果n小于当前容器的大小,则删除末尾的元素以缩小容器。

如果n大于当前容器的大小,则通过在末尾插入新元素来扩展容器。

如果提供了第二个参数val,那么新添加的元素会被初始化为val的副本;如果没有提供第二个参数,则使用默认构造函数来初始化新元素

访问和遍历

1)迭代器(正向迭代器和反向迭代器)

iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
reverse_iterator rend();
const_reverse_iterator rend() const;
  • begin() 返回指向容器中第一个元素的迭代器。
  • end() 返回指向容器中最后一个元素之后位置的迭代器。
  • rbegin() 返回指向容器中最后一个元素的逆向迭代器。
  • rend() 返回指向容器中第一个元素之前位置的逆向迭代器。
  • const_iteratorconst_reverse_iterator 类型的迭代器只能用于读取元素,不能用于修改元素。

2)front and back

reference front();
const_reference front() const;
reference back();
const_reference back() const;
  • front() 返回对容器中第一个元素的引用。
  • back() 返回对容器中最后一个元素的引用。
  • const_reference 类型的引用只能用于读取元素,不能用于修改元素

list的增删查改

1)push_front

void push_front(const value_type& val);

list的开始处插入一个新元素,这个元素是val的副本

2)push_back

void push_back(const value_type& val);

list的末尾添加一个新元素,这个元素是val的副本

3)pop_front

void pop_front();

删除list中的第一个元素

4)pop_back

void pop_back();

删除list中的最后一个元素

5)find

template <class InputIterator, class T>
InputIterator find(InputIterator first, InputIterator last, const T& val);

list中查找值为val的第一个元素,返回一个指向该元素的迭代器,如果未找到则返回last

注意:find不是list的成员函数,而是算法的一部分,通常在<algorithm>头文件中定义

6)insert

iterator insert(iterator position, const value_type& val);
void insert(iterator position, size_type n, const value_type& val);
template <class InputIterator>
void insert(iterator position, InputIterator first, InputIterator last);

position指定的位置插入一个新元素val,或者插入n个值为val的元素,或者插入由迭代器范围[first, last)指定的元素序列

7)erase

iterator erase(iterator position);
iterator erase(iterator first, iterator last);

删除由position指定的单个元素,或者删除由迭代器范围[first, last)指定的元素序列

注: list的insert和erase会不会造成迭代器失效的问题?

listinserterase 操作不会导致迭代器失效

解释:

  • insert:在 list 中插入元素时,由于 list 是由双向链表实现的,插入操作会创建新的节点并将其链接到链表中,不会影响到其他节点的内存位置,因此所有迭代器(包括指向插入点之前、之后和插入点本身的迭代器)仍然有效。
  • erase:当从 list 中删除元素时,只会移除特定的节点并重新链接其前后的节点,而不会影响其他节点的位置。因此,除了被擦除元素的那个迭代器外,其他迭代器仍然有效。

简单来说:


  • insert:非侵入式节点插入,迭代器保持有效。
  • erase:节点移除,仅影响目标迭代器,其他迭代器保持有效

8)swap

void swap(list& other);

交换两个list容器的内容,这个操作非常高效,因为它只交换内部数据结构,而不需要交换实际的元素

9)assign

void assign(size_t n, const value_type& val);
template <class InputIterator>
void assign(InputIterator first, InputIterator last);

list的内容替换为n个值为val的元素,或者替换为由迭代器范围[first, last)指定的元素序列

10)clear

void clear();

删除list中的所有元素,使容器变为空

list顺序修改接口

void reverse();

reverse 函数会反转 list 中元素的顺序。也就是说,列表中的第一个元素会变成最后一个元素,第二个元素会变成倒数第二个元素,以此类推。

这个操作会就地(in-place)进行,不需要额外的存储空间。调用这个函数后,列表的迭代器、引用和指针仍然有效,但它们现在会指向反转后的列表中的不同元素

目录
相关文章
|
1月前
|
存储 搜索推荐 C++
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
48 2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
|
30天前
|
存储 编译器 对象存储
【C++打怪之路Lv5】-- 类和对象(下)
【C++打怪之路Lv5】-- 类和对象(下)
27 4
|
30天前
|
编译器 C语言 C++
【C++打怪之路Lv4】-- 类和对象(中)
【C++打怪之路Lv4】-- 类和对象(中)
23 4
|
30天前
|
存储 算法 调度
【C++打怪之路Lv11】-- stack、queue和优先级队列
【C++打怪之路Lv11】-- stack、queue和优先级队列
32 1
|
30天前
|
存储 C++ 索引
【C++打怪之路Lv9】-- vector
【C++打怪之路Lv9】-- vector
20 1
|
30天前
|
存储 安全 C++
【C++打怪之路Lv8】-- string类
【C++打怪之路Lv8】-- string类
21 1
|
30天前
|
编译器 程序员 C++
【C++打怪之路Lv7】-- 模板初阶
【C++打怪之路Lv7】-- 模板初阶
16 1
|
30天前
|
存储 C语言 C++
【C++打怪之路Lv6】-- 内存管理
【C++打怪之路Lv6】-- 内存管理
37 0
【C++打怪之路Lv6】-- 内存管理
|
1月前
|
存储 C++ 容器
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器1
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
52 5
|
1月前
|
存储 编译器 C++
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
53 2