C++容器——单向链表(forward_list)

1. 简介

forward_list是一个单链表结构的容器,支持从容器中的任何位置快速插入和删除元素,不支持快速随机访问。与std::list相比,其不是双向迭代的,但该容器节省了存储空间;

头文件和定义

#include <forward_list>

template<
    class T,
    class Allocator = std::allocator<T>
> class forward_list;

2. 初始化

初始化分为直接初始化,拷贝初始化和赋值初始化;

/*
* @brief forward_list
* g++ -g forward_list_main.cc -o d -std=c++11
* 
*/

#include <iostream>
#include <forward_list>
#include <string>
#include <iterator>

template<typename T>
void showInfo(T &t)
{
	for(auto &au : t)
	{
		std::cout<<au<<" ";
	}
	std::cout<<std::endl;
}

int main(int argc, char *argv[])
{
	std::forward_list<int32_t> fl_1;
    fl_1 = {11,21,31,41,51,61};   
    showInfo(fl_1);

    std::forward_list<int32_t> fl_2{100,200,300};
    showInfo(fl_2);

    std::forward_list<int32_t> fl_3 = fl_1;
    showInfo(fl_3);

    std::forward_list<std::string> fl_4 = {"c++","c","python","shell"};
    showInfo(fl_4);   

	
	return 0;
}

输出

11 21 31 41 51 61
100 200 300
11 21 31 41 51 61
c++ c python shell

3. 使用

3.1 元素的访问

forward_list不支持下标访问,例如at()[]

方法说明
front链表头元素
iterator迭代器访问元素

3.2 元素的大小

forward_list没有size()函数,可以通过distance来计算容器的大小;

方法说明
empty数组判空
max_size最大容量
resize改变大小
clear清空size大小
swap交换两个forward_list的内容

示例

int main(int argc, char *argv[])
{
	std::forward_list<int32_t> fl_1;
    fl_1 = {11,21,31,41,51,61};   

	auto begin_iter = fl_1.begin();
	auto end_iter = fl_1.end();

	auto size = std::distance(begin_iter,end_iter);
	std::cout<<"size is: "<<size<<std::endl;

	fl_1.resize(100);
	begin_iter = fl_1.begin();
	end_iter = fl_1.end();
	size = std::distance(begin_iter,end_iter);
	std::cout<<"size is: "<<size<<std::endl;	
	
	return 0;
}

结果

size is: 6
size is: 100

3.3 元素的修改

主要包括元素的赋值、插入和删除等,相关的操作和list还是存在差异

方法说明
assign重新对list赋值
=直接赋值
get_allocator返回内存分配器
insert_after在迭代器之后插入元素
emplace_after在迭代器之后插入元素
push_front头部插入元素,先复制元素,在将元素插入到头部
emplace_front头部插入元素,直接在数组尾部创建元素
erase_after删除迭代器位置之后的元素
pop_front删除头部元素
int main(int argc, char *argv[])
{
	std::forward_list<std::string> fl_1{"c++","c","python","shell","java"};
	showInfo(fl_1);
	std::cout<<std::endl;

	fl_1.insert_after(fl_1.begin(), "R");   //第二个元素
	showInfo(fl_1);
	std::cout<<std::endl;

	fl_1.insert_after(fl_1.before_begin(),"golang");   //是首元素
	showInfo(fl_1);
	std::cout<<std::endl;

	fl_1.emplace_after(fl_1.begin(),"php");   //成为第二个元素	
	showInfo(fl_1);
	std::cout<<std::endl;

	fl_1.push_front("Qt");   //插入到队列头
	showInfo(fl_1);
	std::cout<<std::endl;

	fl_1.emplace_front("matlab");  //插入到队列头
	showInfo(fl_1);
	std::cout<<std::endl;

	fl_1.pop_front();    //删除元素
	showInfo(fl_1);
	std::cout<<std::endl;

	fl_1.erase_after(fl_1.begin());  //删除fl_1队列中的第二个元素
	//fl_1.erase_after(fl_1.before_begin());  //删除fl_1队列中的第一个元素
	showInfo(fl_1);
	
	return 0;
}

结果

c++ c python shell java

c++ R c python shell java

golang c++ R c python shell java

golang php c++ R c python shell java

Qt golang php c++ R c python shell java

matlab Qt golang php c++ R c python shell java

Qt golang php c++ R c python shell java

Qt php c++ R c python shell java

3.4 元素的操作

方法说明
merge将forward_list2以递增的顺序合并两个forward_list1中,forward_list1中的元素不会进行排序
splice_after剪贴函数,将forward_list1中的元素剪贴到forward_list2中,将其放在之后
remove删除指定值的元素
remove_if删除指定条件的元素
reverse反序
unique去重
sort排序
int main(int argc, char *argv[])
{
	std::forward_list<int32_t> fl_1;
    fl_1 = {11,21,31,41,51,61};   
    showInfo(fl_1);

    std::forward_list<int32_t> fl_2{25,55,300};
    showInfo(fl_2);

	auto iter = fl_1.begin();
	//std::advance(iter, 2);
	fl_1.splice_after(iter,fl_2);  //放在begin的后面
	showInfo(fl_1);
	
	return 0;
}

输出

11 21 31 41 51 61
25 55 300
11 25 55 300 21 31 41 51 61

3.5 迭代器

迭代器和list相比有所不同,增加了befor_begin相关操作,但是没有rbegin等相关操作;

迭代器最好结合STL中的算法一起使用;迭代器的返回值最好用auto接受;

迭代器的类型包括:iterator、const_iterator、reverse_iterator和const_reverse_iterator

方法说明
begin返回forward_list的头元素(迭代器),其值可修改
end返回forward_list的尾元素(迭代器),其值可修改
cbegin返回forward_list的头元素(迭代器),其值不可修改,const属性
cend返回forward_list尾元素(迭代器),其值不可修改,const属性
befor_begin返回forward_list的头元素之前的位置(迭代器)
cbefor_begin返回forward_list的头元素之前的位置(迭代器),const属性

示例

int main(int argc, char *argv[])
{
	std::forward_list<int32_t> fl_1;
    fl_1 = {11,21,31,41,51,61};   
    
	auto iter_1 = fl_1.begin();   //std::forward_list<int32_t>::iterator
	auto iter_2 = fl_1.cbegin();  //std::forward_list<int32_t>::const_iterator
	auto iter_3 = fl_1.end();     //std::forward_list<int32_t>::iterator
	auto iter_4 = fl_1.cend();    			//std::forward_list<int32_t>::const_iterator
	auto iter_5 = fl_1.before_begin();		//std::forward_list<int32_t>::iterator
	auto iter_6 = fl_1.cbefore_begin();		//std::forward_list<int32_t>::const_iterator

	std::cout<<"begin() \t" << *iter_1 << std::endl;
	std::cout<<"cbegin() \t" << *iter_2 << std::endl;

	while (iter_1 != iter_3)	
	{
		std::cout<<*iter_1<<" ";
		iter_1++;
	}
	std::cout<<std::endl;
	
	while (iter_2 != iter_4)	
	{
		std::cout<<*iter_2<<" ";
		iter_2++;
	}
	std::cout<<std::endl;
	
	std::advance(iter_5,1);  //向前移动1个位置
	std::cout<<"before_begin() \t\t" << *iter_5 << std::endl;

	std::advance(iter_6,2);  //向前移动2个位置
	std::cout<<"cbefore_begin() \t" << *iter_6 << std::endl;
	
	return 0;
}

结果

begin()         11
cbegin()        11
11 21 31 41 51 61
11 21 31 41 51 61
before_begin()          11
cbefore_begin()         21

迭代器的辅助函数
辅助函数的使用需要包含头文件

#include <iterator>
方法说明
advance移动迭代器的位置
distance计算两个迭代器的距离
begin返回容器第一个元素的迭代器
end返回容器最后一个元素的迭代器
prev迭代器向前移动一个元素
next迭代器向后移动一个元素
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值