您的位置:首页 > 房产 > 家装 > 一篇搞懂C++ STL 单向链表std::forward_list

一篇搞懂C++ STL 单向链表std::forward_list

2025/3/10 6:11:39 来源:https://blog.csdn.net/m0_62599305/article/details/141720671  浏览:    关键词:一篇搞懂C++ STL 单向链表std::forward_list

文章目录

  • 前言
  • 什么是`std::forward_list`
  • `std::forward_list`与`std::list`的区别
  • `std::forward_list`的构造函数
  • `std::forward_list`的操作函数
  • 示例代码
  • 总结


前言

C++标准模板库(STL)提供了多种容器类来处理不同的数据结构,其中std::forward_list是用于实现单向链表(Singly Linked List)的容器。与其他容器如std::liststd::vector相比,std::forward_list更为轻量,专为需要快速插入和删除操作、以及内存效率的应用场景而设计。本篇文章将详细介绍std::forward_list的特性、与std::list的区别、所有构造函数和操作函数,并通过示例代码帮助你全面理解这一容器的使用方法。


什么是std::forward_list

std::forward_list 是C++11引入的单向链表容器。它的设计非常简单,仅包含指向下一个节点的指针,因此与双向链表(std::list)相比,它占用的内存更少。由于其单向链表的性质,std::forward_list 只能高效地在头部进行插入和删除操作,遍历时只能从头到尾单向访问。

std::forward_liststd::list的区别

std::list是双向链表容器,具有指向前后两个节点的指针,因此可以在头部和尾部进行高效的插入和删除操作,并且支持双向遍历。而std::forward_list则仅有一个指向下一个节点的指针,无法进行反向遍历,也无法在尾部高效地插入或删除。

通过一个简单的字符串图可以更清晰地理解这两者的区别:

// std::forward_list(单向链表)
headv
+---+    +---+    +---+
| 1 | -> | 2 | -> | 3 |
+---+    +---+    +---+// std::list(双向链表)
head                 tailv                    ^
+---+    +---+    +---+
| 1 | <->| 2 | <->| 3 |
+---+    +---+    +---+

如图所示,std::forward_list 只能从头到尾进行单向遍历,而std::list 可以在任意方向上遍历,并且更灵活,但代价是更高的内存开销。

std::forward_list的构造函数

  1. 默认构造函数
    创建一个空的forward_list容器。

    std::forward_list<int> flist;
    
  2. 指定大小的构造函数
    创建一个包含n个默认初始化元素的forward_list

    std::forward_list<int> flist(5);  // 创建一个包含5个默认值为0的元素的forward_list
    
  3. 指定大小和初始值的构造函数
    创建一个包含n个元素,每个元素的值为val

    std::forward_list<int> flist(5, 10);  // 创建一个包含5个值为10的元素的forward_list
    
  4. 区间构造函数
    创建一个forward_list,初始化为迭代器范围[first, last)内的元素。

    std::vector<int> vec = {1, 2, 3, 4, 5};
    std::forward_list<int> flist(vec.begin(), vec.end());  // 用vector的元素初始化forward_list
    
  5. 复制构造函数
    创建一个forward_list,它是另一个forward_list的副本。

    std::forward_list<int> flist1 = {1, 2, 3, 4, 5};
    std::forward_list<int> flist2(flist1);  // 复制flist1
    
  6. 移动构造函数
    创建一个forward_list,通过移动另一个forward_list的内容来初始化。

    std::forward_list<int> flist1 = {1, 2, 3, 4, 5};
    std::forward_list<int> flist2(std::move(flist1));  // 移动flist1到flist2
    

std::forward_list的操作函数

  1. push_front()
    在链表头部插入元素。

    std::forward_list<int> flist = {2, 3, 4};
    flist.push_front(1);  // flist = {1, 2, 3, 4}
    
  2. pop_front()
    删除链表头部的元素。

    std::forward_list<int> flist = {1, 2, 3, 4};
    flist.pop_front();  // flist = {2, 3, 4}
    
  3. insert_after()
    在指定位置之后插入元素或元素序列。

    std::forward_list<int> flist = {1, 3, 4};
    auto it = flist.insert_after(flist.begin(), 2);  // 在1之后插入2,flist = {1, 2, 3, 4}
    
  4. erase_after()
    删除指定位置之后的元素。

    std::forward_list<int> flist = {1, 2, 3, 4};
    flist.erase_after(flist.begin());  // 删除2,flist = {1, 3, 4}
    
  5. front()
    返回链表头部的元素。

    std::forward_list<int> flist = {1, 2, 3, 4};
    int frontElem = flist.front();  // frontElem = 1
    
  6. clear()
    清空链表中的所有元素。

    std::forward_list<int> flist = {1, 2, 3, 4};
    flist.clear();  // flist = {}
    
  7. empty()
    判断链表是否为空。

    std::forward_list<int> flist;
    bool isEmpty = flist.empty();  // isEmpty = true
    
  8. size()
    由于std::forward_list的单向链表特性,它没有直接提供size()函数来获取元素个数。通常你需要手动遍历链表来计算元素的数量:

    std::forward_list<int> flist = {1, 2, 3, 4};
    size_t size = std::distance(flist.begin(), flist.end());  // size = 4
    

示例代码

#include <iostream>
#include <forward_list>
#include <iterator>int main() {// 创建一个单向链表std::forward_list<int> flist = {3, 4, 5};// 在链表头部插入元素flist.push_front(2);  // flist = {2, 3, 4, 5}flist.push_front(1);  // flist = {1, 2, 3, 4, 5}// 插入元素到指定位置后auto it = flist.insert_after(flist.begin(), 6);  // flist = {1, 6, 2, 3, 4, 5}// 删除指定位置后的元素flist.erase_after(flist.begin());  // flist = {1, 2, 3, 4, 5}// 删除头部元素flist.pop_front();  // flist = {2, 3, 4, 5}// 获取链表头部的元素std::cout << "Front element: " << flist.front() << std::endl;  // Front element: 2// 遍历链表并输出每个元素std::cout << "Elements in forward_list: ";for (int n : flist) {std::cout << n << " ";}std::cout << std::endl;// 计算链表中的元素个数size_t size = std::distance(flist.begin(), flist.end());std::cout << "Size of forward_list: " << size << std::endl;  // Size of forward_list: 4// 清空链表flist.clear();std::cout << "Size after clearing: " << std::distance(flist.begin(), flist.end()) << std::endl;  // Size after clearing: 0return 0;
}

总结

std::forward_list 是一个轻量级的单向链表容器,适用于内存开销敏感的场景,以及需要高效进行

头部插入和删除的场景。尽管它在功能上不如std::list全面,但它的简单性使得它在特定应用中更具优势。通过理解std::forward_list的构造函数和操作函数,并结合实际需求,你可以选择合适的容器来优化程序的性能和内存使用。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com