【C++】list的使用(上)

简介: 迭代器在STL中统一了访问接口,如`list`的`begin()`和`end()`。示例展示了如何使用正向和反向迭代器遍历`list`。注意`list`的迭代器不支持加减操作,只能用`++`和`--`。容器的`empty()`和`size()`用于检查状态和获取元素数。`front()`和`back()`访问首尾元素,`assign()`重载函数用于替换内容,`push_*/pop_*`管理两端元素,`insert()`插入元素,`erase()`删除元素,`resize()`调整大小,`clear()`清空容器。这些接口与`vector`和`string`类似,方便使用。

🔥迭代器接口(Iterators)

在这里插入图片描述
对于STL的各种容器,迭代器的规则都是极其相似的。

和vector和string相同,begin获取指向list对象首元素的迭代器,end指向链表尾元素下一位的迭代器。

我认为迭代器在vector和string的基础上可以直接上代码了,大家能直接了解其用法。

代码案例:

#include<iostream>
#include<list>
using namespace std;

int main()
{
   
   
    list<int> lt({
   
    1,2,3,4 });

    // 获取正向迭代器遍历
    list<int>::iterator it = lt.begin();
    while (it != lt.end()) {
   
   
        cout << *it << " ";
        ++it;
    }
    cout << endl;

    // 获取反向迭代器遍历
    list<int>::reverse_iterator rit = lt.rbegin();
    while (rit != lt.rend()) {
   
   
        cout << *rit << " ";
        ++rit;
    }
    cout << endl;

    return 0;
}

在这里插入图片描述
不过在使用list迭代器需要特别注意的一点:list链表的迭代器不支持加减运算,只支持++和- -运算符,如it += 1it = it + 3的写法会使编译器报错。

🔥容量获取接口(Capacity)

在这里插入图片描述

==empty和size==

bool empty() const;

判断list对象是否为空

size_type size() const;

获取list对象元素个数

代码案例:

#include<iostream>
#include<list>
using namespace std;

int main()
{
   
   
    list<int> lt1;
    list<int> lt2({
   
    1,2,3,4 });

    cout << "lt1.empty():" << lt1.empty() << endl;
    cout << "lt2.empty():" << lt2.empty() << endl;
    cout << endl;

    cout << "lt1.size():" << lt1.size() << endl;
    cout << "lt2.size():" << lt2.size() << endl;

    return 0;
}

在这里插入图片描述

🔥元素获取(Element access)

在这里插入图片描述

  reference front();
const_reference front() const;

获取list对象首元素

reference back();
const_reference back() const;

获取list对象尾元素

代码案例:

#include<iostream>
#include<list>
using namespace std;

int main()
{
   
   
    list<int> lt({
   
    1,2,3,4 });

    cout << lt.front() << endl;
    cout << lt.back() << endl;

    return 0;
}

在这里插入图片描述

🔥修改器(Modifiers)

在这里插入图片描述

==assign==

在这里插入图片描述
range (1)

template <class InputIterator>
  void assign (InputIterator first, InputIterator last);

fill (2)

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

两个重载都可以给list对象分配新内容,将对象原有的内容覆盖。

代码案例:

#include<iostream>
#include<list>
using namespace std;

int main()
{
   
   
    list<int> lt1({
   
    1,2,3,4 });
    list<int> lt2({
   
    0,0,0,0 });

    lt1.assign(lt2.begin(), lt2.end());
    for (auto e : lt1) {
   
   
        cout << e << " ";
    }
    cout << endl;

    lt1.assign(8, -1);
    for (auto e : lt1) {
   
   
        cout << e << " ";
    }
    return 0;
}

在这里插入图片描述

==push_back,pop_back,push_front和pop_front==

分别对应着链表的尾插尾删和头插头删

代码案例:

#include<iostream>
#include<list>
using namespace std;

int main()
{
   
   
    list<int> lt({
   
    0,0,0 });

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

    lt.push_back(-1);
    for (auto e : lt) {
   
    cout << e << " "; }
    cout << endl;

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

    lt.push_front(-1);
    for (auto e : lt) {
   
    cout << e << " "; }
    cout << endl;

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

    return 0;
}

在这里插入图片描述

==insert==

在这里插入图片描述
single element (1)

iterator insert (iterator position, const value_type& val);

在迭代器指向元素之前插入val。
fill (2)

void insert (iterator position, size_type n, const value_type& val);

在迭代器指向元素之前插入n个val。
range (3)

template <class InputIterator>
    void insert (iterator position, InputIterator first, InputIterator last);

在迭代器指向元素之前按顺序插入迭代器区间[first, last)内的值。

带吗案例:

#include <iostream>
#include <list>
#include <vector>

int main()
{
   
   
    std::list<int> mylist;
    std::list<int>::iterator it;

    // set some initial values:
    for (int i = 1; i <= 5; ++i) mylist.push_back(i); // 1 2 3 4 5

    it = mylist.begin();
    ++it;       // it points now to number 2           ^

    mylist.insert(it, 10);                        // 1 10 2 3 4 5

    // "it" still points to number 2                      ^
    mylist.insert(it, 2, 20);                      // 1 10 20 20 2 3 4 5

    --it;       // it points now to the second 20            ^

    std::vector<int> myvector(2, 30);
    mylist.insert(it, myvector.begin(), myvector.end());
    // 1 10 20 30 30 20 2 3 4 5
    //               ^
    std::cout << "mylist contains:";
    for (it = mylist.begin(); it != mylist.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    return 0;
}

在这里插入图片描述

==erase==

在这里插入图片描述

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

删除list容器中一个迭代器(position)指向的元素或者一段迭代器区间(first, last]内的元素
返回值为指向被删除元素下一元素的迭代器

代码案例:

#include<iostream>
#include<list>
using namespace std;

int main()
{
   
   
    list<int> lt({
   
    1,2,3,4,5 });
    for (auto e : lt) {
   
    cout << e << " "; }
    cout << endl;

    list<int>::iterator it = lt.begin();
    ++it;
    it = lt.erase(it);
    for (auto e : lt) {
   
    cout << e << " "; }
    cout << endl;

    it = lt.erase(it, lt.end());
    for (auto e : lt) {
   
    cout << e << " "; }
    cout << endl;

    return 0;
}

在这里插入图片描述

==resize==

void resize (size_type n, value_type val = value_type());

此接口函数用于调整容器的大小,使其包含n个元素。
如果n小于当前容器的大小,内容将被缩减为其前n个元素,移除超出n的部分(并销毁它们)。
如果n大于当前容器的大小,内容将通过在末尾插入所需数量的新元素来扩展,以达到大小为n。如果指定了val,新元素将被初始化为val的副本;否则,它们将进行默认值初始化。

// resizing list
#include <iostream>
#include <list>

int main()
{
   
   
    std::list<int> mylist;

    // set some initial content:
    for (int i = 1; i < 10; ++i) mylist.push_back(i);

    mylist.resize(5);
    mylist.resize(8, 100);
    mylist.resize(12);

    std::cout << "mylist contains:";
    for (std::list<int>::iterator it = mylist.begin(); it != mylist.end(); ++it)
        std::cout << ' ' << *it;

    std::cout << '\n';

    return 0;
}

在这里插入图片描述

==clear==

void clear();

从列表容器(其中的元素将被销毁)中移除所有元素,使size的大小变为0

结语

本篇博客给大家初步介绍了list,其底层是一个双向循环链表,讲解了list的一些函数接口,如修改器,元素访问,以及迭代器接口的使用方式。这些功能和规则和vector,string的接口大同小异,名称也大都一致,降低了我们的学习成本。
博主后续还会产出更多有关于STL的内容,感谢大家的支持。♥

相关文章
|
5天前
|
算法 C语言 C++
【c++丨STL】list的使用
本文介绍了STL容器`list`的使用方法及其主要功能。`list`是一种双向链表结构,适用于频繁的插入和删除操作。文章详细讲解了`list`的构造函数、析构函数、赋值重载、迭代器、容量接口、元素访问接口、增删查改操作以及一些特有的操作接口如`splice`、`remove_if`、`unique`、`merge`、`sort`和`reverse`。通过示例代码,读者可以更好地理解如何使用这些接口。最后,作者总结了`list`的特点和适用场景,并预告了后续关于`list`模拟实现的文章。
22 7
|
14天前
|
存储 编译器 C++
C++ initializer_list&&类型推导
在 C++ 中,`initializer_list` 提供了一种方便的方式来初始化容器和传递参数,而右值引用则是实现高效资源管理和移动语义的关键特性。尽管在实际应用中 `initializer_list&&` 并不常见,但理解其类型推导和使用方式有助于深入掌握现代 C++ 的高级特性。
16 4
|
2月前
|
存储 搜索推荐 C++
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
59 2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
|
2月前
|
存储 算法 C++
【C++打怪之路Lv10】-- list
【C++打怪之路Lv10】-- list
22 1
|
2月前
|
存储 C++ 容器
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器1
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
65 5
|
2月前
|
存储 编译器 C++
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
73 2
|
2月前
|
C++
【C++】C++ STL 探索:List使用与背后底层逻辑(三)
【C++】C++ STL 探索:List使用与背后底层逻辑
|
2月前
|
C++
【C++】C++ STL 探索:List使用与背后底层逻辑(二)
【C++】C++ STL 探索:List使用与背后底层逻辑
|
2月前
|
存储 编译器 C++
【C++】C++ STL 探索:List使用与背后底层逻辑(一)
【C++】C++ STL 探索:List使用与背后底层逻辑
|
2月前
|
存储 缓存 C++
C++番外篇——list与vector的比较
C++番外篇——list与vector的比较
26 0