【STL详解 —— list的介绍及使用】

list的介绍

  1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。
  2. list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向
    其前一个元素和后一个元素。
  3. list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高
    效。
  4. 与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率
    更好。
  5. 与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list
    的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间
    开销;list还需要一些额外的空间,以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这
    可能是一个重要的因素)

list的介绍使用

list的构造

  1. 默认构造函数:创建一个空的list容器。
	list<int> v;
  1. 填充构造函数:创建一个具有特定大小的list,可以指定元素的初始值。
	list(size_type n,const value_type& val = value_type())
  1. 拷贝构造函数: 通过复制另一个list来创建一个新的list。
	list (const list& x)
  1. 范围构造函数:通过复制另一个容器或数组的元素范围来创建list。
	list (Inputlterator first, Inputlterator last)
	//用[first,last)区间中的元素构造list

示例:

	list<int> l1;                         // 构造空的l1
    list<int> l2(4, 100);                 // l2中放4个值为100的元素
    list<int> l3(l2.begin(), l2.end());  // 用l2的[begin(), end())左闭右开的区间构造l3
    list<int> l4(l3);                    // 用l3拷贝构造l4


	 // 以数组为迭代器区间构造l5
    int array[] = { 16,2,77,29 };
    list<int> l5(array, array + sizeof(array) / sizeof(int));

    // 列表格式初始化C++11
    list<int> l6{ 1,2,3,4,5 };

list iterator的使用

此处,大家可暂时将迭代器理解成一个指针,该指针指向list中的某个节点。

  1. begin()
iterator begin();const_iterator begin() const;
  1. end()
iterator end();const_iterator end() const;
  1. rbegin()
reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
  1. rend()
reverse_iterator rend();
const_reverse_iterator rend() const;

在这里插入图片描述

示例

	// 用迭代器方式打印l1中的元素
    list<int>::iterator it = l1.begin();
    while (it != l1.end())
    {
        cout << *it << " ";
        ++it;
    }       
    cout << endl;

    // C++11范围for的方式遍历
    for (auto& e : l1)
        cout << e << " ";

    cout << endl;

list capacity

  1. empty()
    检测list是否为空,是返回true,否则返回false
bool empty() const;
  1. size()
    返回list中有效节点的个数
size_type size() const;

示例:

list<int> lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	lt.push_back(5);

	for (auto& e : lt)
	{
		cout << e << " ";
	}
	cout << endl;

	cout << "lt.size = " << lt.size() << endl;
	

在这里插入图片描述

list element access

  1. front()
    返回list的第一个节点中值的引用
T& front();
  1. back()
    返回list的最后一个节点中值的引l用
const T& front() const;

示例:

list<int> lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	lt.push_back(5);

	for (auto& e : lt)
	{
		cout << e << " ";
	}
	cout << endl;

	lt.front()++;	//给lt的第一个元素+1
	lt.back()++;	//给lt的最后一个元素+1

	for (auto& e : lt)
	{
		cout << e << " ";
	}
	cout << endl;

	cout << "lt.size = " << lt.size() << endl;

在这里插入图片描述

list modifiers

  1. push_front()
    在list首元素前插入值为val的元素
	void push_front (const value_type& val); 
  1. pop front()
    删除list中第一个元素
void pop_front();
  1. push back()
    在list尾部插入值为val的元素
void push_back (const value_type& val);
  1. pop back()
    删除list中最后一个元素
void pop_back();
  1. insert()
    在listposition位置中插入值为val的元素
single element (1):	
	iterator insert (iterator position, const value_type& val);

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

  1. erase()
    删除listposition位置的元素
iterator erase (iterator position);iterator erase (iterator first, iterator last);
  1. swap()
    交换两个list中的元素
void swap (list& x);
  1. clear()
    清空list中的有效元素

示例

void clear();
#include <iostream>
#include <list>

using namespace std;

int main() {
    // 创建一个空的 list
    list<int> mylist;

    // push_front 在 list 首元素前插入值为 val 的元素
    mylist.push_front(10);
    mylist.push_front(20);
    mylist.push_front(30);

    // 输出 list 中的元素
    cout << "List after push_front:";
    for (int& x : mylist) {
        cout << " " << x;
    }
    cout << endl;

    // pop_front 删除 list 中的第一个元素
    mylist.pop_front();

    // 输出 list 中的元素
    cout << "List after pop_front:";
    for (int& x : mylist) {
        cout << " " << x;
    }
    cout << endl;

    // push_back 在 list 尾部插入值为 val 的元素
    mylist.push_back(40);
    mylist.push_back(50);

    // 输出 list 中的元素
    cout << "List after push_back:";
    for (int& x : mylist) {
        cout << " " << x;
    }
    cout << endl;

    // pop_back 删除 list 中的最后一个元素
    mylist.pop_back();

    // 输出 list 中的元素
    cout << "List after pop_back:";
    for (int& x : mylist) {
        cout << " " << x;
    }
    cout << endl;

    // insert 在 list 中的 position 位置插入值为 val 的元素
    list<int>::iterator it = mylist.begin();
    advance(it, 1); // 将迭代器移动到第二个位置
    mylist.insert(it, 35);

    // 输出 list 中的元素
    cout << "List after insert:";
    for (int& x : mylist) {
        cout << " " << x;
    }
    cout << endl;

    // erase 删除 list 中的 position 位置的元素
    it = mylist.begin();
    advance(it, 2); // 将迭代器移动到第三个位置
    mylist.erase(it);

    // 输出 list 中的元素
    cout << "List after erase:";
    for (int& x : mylist) {
        cout << " " << x;
    }
    cout << endl;

    // 创建另一个 list
    list<int> another_list = { 100, 200, 300 };

    // swap 交换两个 list 中的元素
    mylist.swap(another_list);

    // 输出交换后的 mylist
    cout << "mylist after swap:";
    for (int& x : mylist) {
        cout << " " << x;
    }
    cout << endl;

    // 输出交换后的 another_list
    cout << "another_list after swap:";
    for (int& x : another_list) {
        cout << " " << x;
    }
    cout << endl;

    // clear 清空 list 中的有效元素
    mylist.clear();

    // 输出清空后的 mylist
    cout << "mylist after clear:";
    for (int& x : mylist) {
        cout << " " << x;
    }
    cout << endl;

    return 0;
}

在这里插入图片描述

list的迭代器失效

前面说过,此处大家可将迭代器暂时理解成类似于指针,迭代器失效即迭代器所指向的节点的无效,即该节
点被删除了。因为list的底层结构为带头结点的双向循环链表,因此在list中进行插入时是不会导致list的迭代
器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响。

void TestListIterator1()
 {
    int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
    list<int> l(array, array+sizeof(array)/sizeof(array[0]));
 
    auto it = l.begin();
    while (it != l.end())
    {
        // erase()函数执行后,it所指向的节点已被删除,因此it无效,在下一次使用it时,必须先给其赋值
        l.erase(it);  
        ++it;
    }
 }


// 改正
void TestListIterator()
{
    int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
    list<int> l(array, array + sizeof(array) / sizeof(array[0]));
    auto it = l.begin();
    while (it != l.end())
    {
        l.erase(it++);
    }
}

相关推荐

  1. NPM介绍使用详解

    2024-04-14 11:06:03       40 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-14 11:06:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-14 11:06:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-14 11:06:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-14 11:06:03       18 阅读

热门阅读

  1. react异步组件如何定义使用 标准使用方法

    2024-04-14 11:06:03       21 阅读
  2. 【React Router】路由搭建

    2024-04-14 11:06:03       20 阅读
  3. LeetCode热题Hot100 - 括号生成

    2024-04-14 11:06:03       15 阅读
  4. 数据仓库—数据仓库的特征

    2024-04-14 11:06:03       13 阅读
  5. jquery删除一个页面元素动画特效

    2024-04-14 11:06:03       21 阅读
  6. 旺旺照妖镜api接口

    2024-04-14 11:06:03       16 阅读
  7. chromedriver最新版下载地址

    2024-04-14 11:06:03       13 阅读
  8. docker网络

    2024-04-14 11:06:03       14 阅读
  9. 从零开始:如何使用Docker构建微服务架构

    2024-04-14 11:06:03       18 阅读
  10. Pytorch中的钩子函数Hook函数

    2024-04-14 11:06:03       15 阅读
  11. C++实现桥接模式代码

    2024-04-14 11:06:03       15 阅读