C++ STL标准库系列文章:

[STL] 1.简介
[STL] 2.序列容器 固定数组array(C++ 11)
[STL] 3.序列容器 动态数组vector
[STL] 4.序列容器 双端队列deque
[STL] 5.序列容器 双向链表list
[STL] 6.序列容器 单向链表forward_list(C++ 11)
[STL] 7.适配器简介
[STL] 8.容器适配器 栈stack
[STL] 9.容器适配器 队列queue
[STL] 10.容器适配器 优先队列priority_queue
[STL] 11.关联容器 集合set
[STL] 12.关联容器 映射map
[STL] 13.关联容器 多重集合multiset
[STL] 14.关联容器 多重映射multimap
[STL] 15.关联容器 无序集合unordered_set(C++ 11)
[STL] 16.关联容器 无序集合unordered_map(C++ 11)
[STL] 17.仿函数functor与函数对象
[STL] 18.预定义函数对象、仿函数适配器
[STL] 19.算法algorithm
[STL] 20.迭代器适配器
[STL] 21.空间配置器allocator

forward_list - C++ Reference (cplusplus.com)

1. 简介

forward_listC++ 11 新添加的一类容器,其底层实现和 list 容器一样,采用的也是链表结构,只不过 forward_list 使用的是单链表,而 list 使用的是双向链表(如下图)

单链表和双向链表

forward_list(单向链表)不支持随机访问,对任何位置进行高效插入、删除的序列容器。与list容器的区别是它是单向的。当不需要双向迭代的时候,forward_list具有更高的效率

forward_list类似于数掮结构的单向链表,通过链表指针串连成逻辑意义上的线性表,因此它的 内存空间不连续

头文件:

#include<forward_list>
using namespace std;

2. 基本使用

#include<iostream>

#include<forward_list>
using namespace std;

int main()
{
   forward_list<int>  l;//构造空的单向链表
   //不提供size()的成员方法,使用算法distance()获取
   cout << l.max_size() << endl;//最大的元素个数

   forward_list<int>  l2(5);//构造5个元素的单向链表,值为类型的默认值
   cout << "第一个元素值:"<<  *l2.begin() << endl;//最大的元素个数

   forward_list<int>  l3(5,111);//构造5个元素的单向链表,每个元素值为111
   cout << "第一个元素值:" << *l3.begin() << endl;//最大的元素个数

   forward_list<int>  l4(l3);//拷贝构造 
   cout << "第一个元素值:" << *l4.begin() << endl;//最大的元素个数

   //验证forward_list的内存结构(不连续)
   for (forward_list<int>::iterator it = l3.begin(); it != l3.end(); ++it)
   {
   	cout << &(*it) << "    ";
   }
   cout << endl;

   return 0;
}

3. 迭代器使用

#include<iostream>

#include<forward_list>
using namespace std;

template<class T>
void   Print(T  begin, T  end)
{
   for (T p = begin; p != end; ++p)
   {
   	cout << *p << "		";
   }
   cout << endl;
}

int main()
{
   forward_list<int>  l3(5, 111);//构造5个元素的单向链表,每个元素值为111
   cout << "第一个元素值:" << *l3.begin() << endl;//最大的元素个数
    
   //验证迭代器类别,forward  iterator 前向迭代器
   cout << typeid(forward_list<int>::iterator::iterator_category).name() << endl;

   //前向迭代器 比 双向迭代器 功能更少一些,支持++、= 、!= 、 == 、 * ,不支持 -- 

   // 支持++    *   =
   forward_list<int>::iterator  it = l3.begin();
  
   *(++it) = 222;
   *(++it) = 333;
   *(++it) = 444;
   *(++it) = 555; //指向最后一个

   ++it;//指向最后一个的下一个
   cout << "是否指向最后一个的下一个" << (it == l3.end()) << endl;

   //--it;//不可以--,因为是单向的

   //const_iterator指向的元素不可赋值
   forward_list<int>::const_iterator  it2 = l3.cbegin();
   //*it2 = 1;//const_iterator指向的元素不可赋值
    
    //正向遍历forward_list 
   for (forward_list<int>::iterator it = l3.begin(); it != l3.end(); ++it)
   {
   	cout << *it << "    ";
   }
   cout << endl;

   //没有反向的迭代器,不支持,因为是单向链表
   //forward_list<int>::reverse_iterator

   //验证Print ,迭代器带来的好处,让算法无需知道容器的细节
   Print<forward_list<int>::iterator>(l3.begin(), l3.end());

   return 0;
}

4. 增加、删除、插入元素

#include<iostream>

#include<forward_list>
using namespace std;

int main()
{
   forward_list<int>  l; 

   /* 温习一下单链表的插入
   pNew->next =  pHead ->next;//新节点的下一个指向插入前的第一个节点
   pHead ->next= pNew;//将头指针指向新节点 
   */
   l.push_front(111);//从头部插入元素
   l.push_front(222);//从头部插入元素
   l.push_front(333);//从头部插入元素
   /*
      为什么没有insert_before() ?
   	pInsert ->next;
   	你无法知道当前节点的前一个节点的地址,所以,你就无法将前一个的pLast->next=pNew
   	
   	为什么insert_after()可以?
   	pNew->next= pInsert->next;
   	pInsert->next = pNew;
   */
   l.insert_after(l.begin(), 444);//在某个迭代器后面插入 

   for (forward_list<int>::iterator it= l.begin()  ;  it !=  l.end(); it++)
   {
   	cout << *it << "    ";
   }
   cout << endl;

   //访问头结点
   cout <<"front():  "<< l.front() << endl; 
   
   /* 温习一下单链表的删除
   pHead ->next= pDelete->next;//将头指针指向删除节点的下一个
   delete pDelete;//删除当前节点
   */
   l.pop_front();//删除头结点


   /*
   为什么没有erase_before(),还是因为,你无法知道pDelete的前一个,
   你就无法将前一个的pLast->next= pDelete->next;

   为什么erase_after()可以?
   pTemp= pDelete->next;
   pDelete->next= pDelete->next->next;
   delete pTemp;
   */
   l.erase_after(l.begin());//删除迭代器节点的下一个

   l.erase_after(l.begin(),l.end());//删除迭代器区间

   l.clear();//删除所有元素

   for (forward_list<int>::iterator it = l.begin(); it != l.end(); it++)
   {
   	cout << *it << "    ";
   }
   cout << endl;

   return 0;
}
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐