04 std::forward_list

forward_list 内部以单项链表方式管理元素, 使用要包含头文件
#include <forward_list>
forward_list是一个行为受限的list,不能走回头路。凡是list没提供的功能,它都不提供。优点是占用内存小,操作速度快。

 

特性

forward_list与list的差异

(1) 只提供向前迭代器,不提供双向迭代器。这意味着,reverse_iterator之类的类型,rbegin,rend,crbegin,crend之类的成员都不能提供
(2) 不提供成员函数size()
(3) 没有指向最末元素的指针, 因此不提供 back(), push_back(), pop_back()
(4) 对于特定位置的插入删除操作, 都提供了特殊版本, 成员函数都带有一个后缀 _after, 例如 insert_after()取代insert()
(5) 提供 before_begin(), cbefore_begin(), 产生出第一个元素之前的一个虚拟位置,可被用来让带有_after后缀的算法交换第一个元素

除了这些差异, forward_list就像是一个list
[1] 不提供随机访问
[2] 在任何位置上插入删除操作都很快
[3] 插入删除,不会造成指向其他元素的指针,引用,迭代器失效
[4] forward_list提供了许多特殊成员函数用于搬移和移除元素,这些函数是一般算法的快速版。然而,只要涉及位置,必须传递给他们目标物的前一个位置

部分操作

c.front()

返回第一个元素

c.push_front(elem)

在头部插入elem的一个拷贝

c.pop_front()

移除第一个元素

c.insert_after(pos,elem)

插入一个elem拷贝与pos之后,返回新元素位置

c.insert_after(pos,n,elem)

插入n个elem的拷贝于pos之后,并返回第一个新元素位置(返回pos如果没有新元素)

c.insert_after(pos,beg,end)

将[beg,end)区间的所有元素复制一份,插入pos位置之后,并返回第一个新元素位置

c.insert_after(pos,initlist)

 

c.emplace_after(pos,args...)

在pos之后插入一个以args为初值的元素,并返回新元素的位置

c.emplace_front(args...)

插入一个以args为初值的元素于起点,不返回任何东西

c.erase_after(pos)

移除pos之后的元素,不返回任何东西

c.erase_after(beg,end)

移除[beg,end)区间的所有元素,不返回任何东西

c.remove(val)

移除所有值为val的元素

c.remove_if(op)

移除所有“造成op(elem)结果为true”的元素

c.resize(num)

将元素数量改为num

c.resize(num,elem)

 

c.clear()

删除所有元素

 

 

c.unique()

删除相邻重复元素只留一个

c.unique(op)

 

c.splice_after(pos,c2)

删除相邻都令op为true的元素只留一个

c.splice_after(pos,c2,c2pos)

将c2所有元素move到c之内,迭代器pos之后

c.splice_after(pos,c2,c2beg,c2end)

将c2内的c2pos所指元素转移到c内的pos所指位置(c和c2可以是同一容器)

c.sort()

以operator< 为准则对所有元素排序

c.sort(op)

以op为准则对所有元素排序

c.merge(c2)

假设c和c2都包含已排序元素,将c2全部元素move到c,并保证合并后所有元素已排序

c.merge(c2,op)

 

c.reverse()

将所有元素反序

 

起始处插入删除元素

 

查找、移除或安插元素

#include <forward_list>
#include "print.hpp"
using namespace std;
int main()
{
	forward_list<int> list = { 1, 2, 3, 4, 5, 97, 98, 99 };
	// find the position before the first even element
	auto posBefore = list.before_begin();
	for (auto pos=list.begin(); pos!=list.end(); ++pos, ++posBefore) {
		if (*pos % 2 == 0) {
			break; // element found
		}
	}
	// and insert a new element in front of the first even element
	list.insert_after(posBefore,42);
	PRINT_ELEMENTS(list);
}

等效查找方法, 使用便捷函数 next()

#include <iterator>
...
auto posBefore = list.before_begin();
for ( ; next(posBefore)!=list.end(); ++posBefore) {
	if (*next(posBefore) % 2 == 0) {
		break; // element found
	}
}

 

自定义算法,找出“拥有特定值”或“满足某个特定条件”的元素的前一位置
 

template <typename InputIterator, typename Tp>
inline InputIterator
find_before (InputIterator first, InputIterator last, const Tp& val)
{
	if (first==last) {
		return first;
	}
	InputIterator next(first);
	++next;
	while (next!=last && !(*next==val)) {
		   ++next;
		   ++first;
	}
	return first;
}

template <typename InputIterator, typename Pred>
inline InputIterator
find_before_if (InputIterator first, InputIterator last, Pred pred)
{
	if (first==last) {
		return first;
	}
	InputIterator next(first);
	++next;
	while (next!=last && !pred(*next)) {
		   ++next;
		   ++first;
	}
	return first;
}

有了这些函数,就可以给出lambda找出所需位置

// find the position before the first even element
auto posBefore = find_before_if (list.before_begin(), list.end(),
								 [] (int i) {
									         return i%2==0;
								 });
// and insert a new element in front of it
list.insert_after(posBefore,42);

运用实例

#include <forward_list>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <string>
using namespace std;
void printLists (const string& s, const forward_list<int>& l1, const forward_list<int>& l2)
{
	cout << s << endl;
	cout << " list1: ";
	copy (l1.cbegin(), l1.cend(), ostream_iterator<int>(cout," "));
	cout << endl << " list2: ";
	copy (l2.cbegin(), l2.cend(), ostream_iterator<int>(cout," "));
	cout << endl;
}

int main()
{
	// create two forward lists
	forward_list<int> list1 = { 1, 2, 3, 4 };
	forward_list<int> list2 = { 77, 88, 99 };
	printLists ("initial:", list1, list2);
	// insert six new element at the beginning of list2
	list2.insert_after(list2.before_begin(),99);
	list2.push_front(10);
	list2.insert_after(list2.before_begin(), {10,11,12,13} );
	printLists ("6 new elems:", list1, list2);
	// insert all elements of list2 at the beginning of list1
	list1.insert_after(list1.before_begin(), list2.begin(), list2.end());
	printLists ("list2 into list1:", list1, list2);
	// delete second element and elements after element with value 99
	list2.erase_after(list2.begin());
	list2.erase_after(find(list2.begin(), list2.end(), 99), list2.end());
	printLists ("delete 2nd and after 99:", list1, list2);
	// sort list1, assign it to list2, and remove duplicates
	list1.sort();
	list2 = list1;
	list2.unique();
	printLists ("sorted and unique:", list1, list2);
	// merge both sorted lists into list1
	list1.merge(list2);
	printLists ("merged:", list1, list2);
}

-----------------------------------------------------------------------------------------
initial:
list1: 1 2 3 4
list2: 77 88 99
6 new elems:
list1: 1 2 3 4
list2: 10 11 12 13 10 99 77 88 99
list2 into list1:
list1: 10 11 12 13 10 99 77 88 99 1 2 3 4
list2: 10 11 12 13 10 99 77 88 99
delete 2nd and after 99:
list1: 10 11 12 13 10 99 77 88 99 1 2 3 4
list2: 10 12 13 10 99
sorted and unique:
list1: 1 2 3 4 10 10 11 12 13 77 88 99 99
list2: 1 2 3 4 10 11 12 13 77 88 99
merged:
list1: 1 1 2 2 3 3 4 4 10 10 10 11 11 12 12 13 13 77 77 88 88 99 99 99
list2:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值