STL容器中 list(双向链表)的增删改查

list(双向链表)

std::list 是 C++ 标准模板库(STL)中的一个容器,它实现了一个双向链表。双向链表中的每个元素都包含三个部分:存储数据的元素本身、指向前一个元素的指针(或迭代器)、以及指向后一个元素的指针(或迭代器)。这使得在链表的任何位置进行插入和删除操作都非常高效,因为这些操作只需要改变指针的指向,而不需要移动其他元素。然而,与数组或 std::vector 相比,随机访问元素的速度较慢,因为访问元素需要从头或尾开始遍历链表。list支持快速的插入和删除操作,但不支持随机访问。

#include <iostream>  
#include <list>  
  
int main() {  
    std::list<int> lst;  
  
    // 向list中添加元素  
    lst.push_back(10);  
    lst.push_front(5);  
  
    // 遍历list  
    for (std::list<int>::iterator it = lst.begin(); it != lst.end(); ++it) {  
        std::cout << "元素: " << *it << std::endl;  
    }  
  
    // 使用范围for循环遍历list(需要C++11及以后,并包含<initializer_list>)  
    // 注意:直接的范围for循环不适用于std::list,但可以使用其他方式模拟  
  
    return 0;  
}  
  
// 注意:由于list不支持随机访问迭代器,因此不能直接使用范围for循环。  
// 可以通过C++11的auto和基于范围的for循环来遍历list,但通常需要额外的辅助,如std::begin和std::end。

插入元素

向 std::list 中插入元素可以使用 insert 方法。它可以在指定位置之前插入一个新元素,也可以插入一个元素范围。

#include <iostream>  
#include <list>  
  
int main() {  
    std::list<int> myList = {1, 2, 4};  
  
    // 在第二个元素之前插入3  
    auto it = myList.begin();  
    std::advance(it, 1); // 移动迭代器到第二个元素  
    myList.insert(it, 3);  
  
    // 遍历并打印  
    for (int elem : myList) {  
        std::cout << elem << " ";  
    }  
    std::cout << std::endl;  
  
    return 0;  
}

删除元素

删除元素可以使用 erase 方法,该方法删除迭代器指向的元素,并返回指向下一个元素的迭代器。

#include <iostream>  
#include <list>  
  
int main() {  
    std::list<int> myList = {1, 2, 3, 4};  
  
    // 删除值为3的元素  
    for (auto it = myList.begin(); it != myList.end(); ) {  
        if (*it == 3) {  
            it = myList.erase(it); // 注意,这里迭代器需要更新  
        } else {  
            ++it;  
        }  
    }  
  
    // 遍历并打印  
    for (int elem : myList) {  
        std::cout << elem << " ";  
    }  
    std::cout << std::endl;  
  
    return 0;  
}

修改元素

修改元素非常简单,直接通过迭代器访问并修改其值。

#include <iostream>  
#include <list>  
  
int main() {  
    std::list<int> myList = {1, 2, 3, 4};  
  
    // 修改第二个元素为10  
    auto it = myList.begin();  
    std::advance(it, 1); // 移动到第二个元素  
    *it = 10;  
  
    // 遍历并打印  
    for (int elem : myList) {  
        std::cout << elem << " ";  
    }  
    std::cout << std::endl;  
  
    return 0;  
}

遍历元素

遍历 std::list 可以使用范围基于的for循环(如上面示例所示),或者使用迭代器手动遍历。

#include <iostream>  
#include <list>  
  
int main() {  
    std::list<int> myList = {1, 2, 3, 4};  
  
    // 使用迭代器遍历  
    for (auto it = myList.begin(); it != myList.end(); ++it) {  
        std::cout << *it << " ";  
    }  
    std::cout << std::endl;  
  
    return 0;  
}

### C++ STL双向链表 `list` 的使用与实现 #### 什么是双向链表双向链表是一种数据结构,其中每个节点不仅存储自身的数据,还保存两个指针:一个指向其前驱节点,另一个指向其后继节点。这种设计使得可以在常量时间内完成在任意位置的插入和删除操作[^3]。 #### 如何定义和初始化 `list` 以下是几种常见的 `list` 定义方式: ```cpp #include <list> #include <iostream> int main() { // 创建一个空的 list std::list<int> myList1; // 创建一个包含 n 个元素的 list,默认值为 0 std::list<int> myList2(5); // 创建一个包含 n 个元素的 list,并赋予初始值 std::list<int> myList3(5, 10); // 通过拷贝现有 list 来创建新的 list std::list<int> myList4(myList3); return 0; } ``` #### 迭代器的操作 `list` 提供了多种类型的迭代器来遍历列表中的元素。 - **正向迭代器**: 使用 `begin()` 和 `end()` 方法获取。 - **反向迭代器**: 使用 `rbegin()` 和 `rend()` 方法获取。 示例代码如下: ```cpp std::list<int> myList = {1, 2, 3, 4}; // 正向遍历 for(auto it = myList.begin(); it != myList.end(); ++it){ std::cout << *it << " "; } // 反向遍历 for(auto rit = myList.rbegin(); rit != myList.rend(); ++rit){ std::cout << *rit << " "; } ``` #### 访问和修改方法 可以通过以下成员函数访问或修改 `list` 中的元素: | 函数名 | 描述 | |----------------|--------------------------------------| | `front()` | 返回第一个元素 | | `back()` | 返回最后一个元素 | 对于修改操作有以下常用函数: - 添加元素到头部或尾部: - `push_front(value)` 将新元素添加至头结点之前[^4]。 - `push_back(value)` 将新元素追加到最后一个节点之后。 - 移除元素: - `pop_front()` 删除并返回第一个元素。 - `pop_back()` 删除并返回最后一个元素。 示例代码展示如何增删元素: ```cpp std::list<int> myList; myList.push_back(10); myList.push_front(20); if(!myList.empty()){ int frontElement = myList.front(); int backElement = myList.back(); myList.pop_front(); myList.pop_back(); } ``` #### 大小和容量管理 可以利用这些功能查询当前大小或者调整分配空间大小: - `size()` 获取实际元素数量。 - `empty()` 判断是否为空集合。 - `resize(new_size)` 调整容器尺寸。 示例演示: ```cpp std::list<int> myList{1, 2, 3}; if (!myList.empty()) { std::cout << "Current size: " << myList.size() << "\n"; } else { std::cout << "The list is empty.\n"; } myList.resize(5, 99); // 扩展到五个元素填充未定部分为99 ``` #### 结合标准算法的应用 因为 `list` 支持双向迭代器,所以能够配合许多通用的标准模板库(STL)算法一起工作,比如查找(`std::find`)、变换(`std::transform`)等[^1]。 示例应用案例: ```cpp #include <algorithm> void findExample(std::list<int>& lst, int targetValue){ auto foundIt = std::find(lst.begin(), lst.end(), targetValue); if(foundIt != lst.end()) std::cout << "Found value at position\n"; else std::cout << "Not Found!\n"; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值