STL之序列式容器

2023-11-12

STL之序列式容器

 

 STL容器即是将运用最广的一些数据结构实现出来,根据其在容器的排列特性,将其分为序列式容器和关联是容器。本文主要记录序列式容器,以及其常用的功能函数。

 

1、vector

vector和数组一样维护了一个连续的线性空间,vector空间运用较灵活,数组是静态空间一旦配置了就无法修改,而vector是动态空间,随着元素的加入其内部机制会动态扩充空间以容纳新元素。

vector常用功能函数:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

/*Menu
01-0-输出vector
01-1-vector 相关函数
01-2-vector 容量大小相关
01-3-vector相关算法
*/

void VecPrint(const vector<int> &v);//01-0
void VecCreate(); //01-1
void VecCapacity(); //01-2
void VecAlgorithm(); //01-3
void VecTraverse(); //01-4

//01-0
void VecPrint(const vector<int> &v)
{
	cout<<"Print Vector!"<<endl;
	cout<<'[';
	for(int i=0;i<v.size();i++)
	{
		if(i==v.size()-1)
		{
			cout<<v[i]<<']'<<endl;
		}else
		{
			cout<<v[i]<<',';
		}
	}
}
//01-1
void VecCreate()
{
	//case 1
	//vector 内存空间一般按照2倍方式增长,但是有的编译器可能按照其它算法增长
	vector<int> v1;
	for(int i=0;i<10;i++)
	{
		v1.push_back(i+1);
		cout<<v1[i]<<'\t'<<v1.capacity()<<endl;
	}
	//case 2
	int arr[] = {1,2,3,4,5,6,7,8,9,10};
	vector<int> v2(arr,arr+sizeof(arr)/sizeof(int));
	VecPrint(v2);
	//case 3
	vector<int> v3(10,6);
	VecPrint(v3);
	for(int i=0;i<3;i++)
	{
		v3.pop_back();
		cout<<v3.capacity()<<endl; //空间分配后就不会自动回收
	}
}
void  TestVecCreate()
{
	VecCreate();
}
//01-2
void VecCapacity()
{
	//case 1
	vector<int> v1;
	for(int i=0;i<10;i++)
	{
		v1.push_back(i+1);
	}
	VecPrint(v1);
	cout<<"Size:"<<v1.size()<<'\t'<<"Capacity:"<<v1.capacity()<<endl;
	//case 2
	v1.resize(5);
	cout<<"Size:"<<v1.size()<<'\t'<<"Capacity:"<<v1.capacity()<<endl;
	//case 3 使用swap回收空间
	vector<int>(v1).swap(v1);//通过匿名对象方式回收空间
	cout<<"Size:"<<v1.size()<<'\t'<<"Capacity:"<<v1.capacity()<<endl;
	VecPrint(v1);
}
void TestVecCapacity()
{
	VecCapacity();
}
//01-3
void VecAlgorithm()
{
	//case 1 开辟10万次数据用了多少空间
	std::vector<int> v;
	int *p = NULL;
	int num = 0;
	for (int i = 0; i < 10000; ++i)
	{
		v.push_back(i);
		if(p!=&v[0])
		{
			p = &v[0];
			num++;
		}
	}
	cout<<num<<endl; //重新分配了num次空间
	//case 2 reserve 预留空间,如果知道空间大致数量的话直接通过reserve预留空间,防止多次重新分配空间,从而提高效率
	std::vector<int> v2;
	v2.reserve(10000);
	int *p2 = NULL;
	int num2 = 0;
	for (int i = 0; i < 10000; ++i)
	{
		v2.push_back(i);
		if(p2!=&v2[0])
		{
			p2 = &v2[0];
			num2++;
		}
	}
	cout<<"reserve:"<<num2<<endl; //重新分配了num次空间
	//case 3 数据存存取
	std::vector<int> v3;
	for(int i=0;i<5;++i)
	{
		v3.push_back(i+1);
	}
	cout<<v3.front()<<endl; //去第一个元素
	cout<<v3.back()<<endl; //取最后一个元素
	//case 4 插入删除
	std::vector<int> v4;
	v4.insert(v4.begin(),10);
	VecPrint(v4);
	v4.insert(v4.begin(),5,6);
	VecPrint(v4);
	v4.pop_back();
	VecPrint(v4);
	v4.insert(v4.end(),5,8);
	VecPrint(v4);
	v4.erase(v4.begin());
	VecPrint(v4);
	v4.erase(v4.begin(),v4.end());
	if(v4.empty())
	{
		cout<<"Is empty!\n";
	}
}
void TestVecAlgorithm()
{
	VecAlgorithm();
}
//01-4
void VecTraverse()
{
	std::vector<int> v;
	for(int i=0;i<10;i++)
		v.push_back(i+1);
	VecPrint(v);
	//case 1 逆序遍历
	//逆序输出需要使用revers_iterator迭代器,否则会出错
	for(vector<int>::reverse_iterator it=v.rbegin();it!=v.rend();it++)
	{
		cout<<*it<<'\t';
	}
	cout<<endl;
	//case 2 vector 迭代器是随机访问迭代器 支持跳跃式访问
	vector<int>::iterator itBegin = v.begin();
	itBegin = itBegin +3;
	cout<<*itBegin<<endl;
}
void TestVecTraverse()
{
	VecTraverse();
}

int main(int argc, char const *argv[])
{
//01-1
	//TestVecCreate();
//-01-2
	//TestVecCapacity();
//-01-3
	//TestVecAlgorithm();
//-01-4
	TestVecTraverse();
	return 0;
}

 

2、deque

deque是一个双向开口的连续线性空间,可在头尾两端分别做元素的删除和插入操作。相对于vector其允许于常数时间内在头部进行插入删除;其没有所谓的容量空间观念,它是动态地以分段连续空间组合而成,随时可以增加一段新的空间并链接起来;其没有vector中的重新分配空间-拷贝-释放等过程。

deque常用功能函数如下:

#include <iostream>
#include <deque>
#include <algorithm>
using namespace std;

/*Menu
02-0-输出deque
02-1- deque创建方法
02-2- deque常用方法
02-3- deque排序方法
*/

void DeqPrint(const deque<int> &d); //02-0
void DeqCreate(); //02-1
void DeqMethod(); //02-2
void DeqAlgorithm(); //02-3

//02-0
void DeqPrint(const deque<int> &d)
{
	cout<<'[';
	for(deque<int>::const_iterator it=d.begin();it!=d.end();it++)
	{
		if(it==d.end()-1)
		{
			cout<<*it<<']'<<endl;	
		}else
		{
			cout<<*it<<',';
		}
	}
}
//02-1
//deque 和vector区别在于其用常数时间在头部插入删除数据
void DeqCreate()
{
	//create method 1
	deque<int> d;
	d.push_back(1);
	d.push_back(2);
	d.push_back(3);
	d.push_back(4);
	DeqPrint(d);
	//create method 2
	deque<int> d2(d.begin(),d.end());
	d2.push_back(100);
	DeqPrint(d2);
	//交换
	cout<<"swap:\n";
	d.swap(d2);
	DeqPrint(d2);
	DeqPrint(d);
}
void TestDeqCreate()
{
	DeqCreate();
}
//02-2
void DeqMethod()
{
	//case 1 
	deque<int> d;
	d.push_back(1);
	d.push_back(2);
	d.push_front(11);
	d.push_front(21);
	DeqPrint(d);
	d.pop_back();
	d.pop_front();
	DeqPrint(d);
	cout<<"Front:"<<d.front()<<'\t'<<"Back:"<<d.back()<<endl;
	//case 2 insert
	deque<int>d2;
	d2.push_back(10);
	d2.push_back(20);
	d2.insert(d2.begin(),d.begin(),d.end());
	DeqPrint(d2);
	//case3 除了头部操作外,其它和vector类似
}
void TestDeqMethod()
{
	DeqMethod();
}
//02-3
bool DeqCompare(int val1,int val2)
{
	return val1>val2;
}
void DeqAlgorithm()
{
	deque<int> d;
	d.push_back(15);
	d.push_back(2);
	d.push_front(11);
	d.push_front(21);
	DeqPrint(d);
	//sort() 正常从小到大
	sort(d.begin(),d.end());
	DeqPrint(d);
	//使用仿函数 设置sort的排序规则
	sort(d.begin(),d.end(),DeqCompare);
	DeqPrint(d);
}
void TestDeqAlgorithm()
{
	DeqAlgorithm();
}

int main(int argc, char const *argv[])
{
//02-1
	//TestDeqCreate();
//02-2
	//TestDeqMethod();
//02-3
	TestDeqAlgorithm();
	return 0;
}

 

3、stack

stack是一种后进先出的容器,其不允许遍历操作,运行新增、移除、取得顶部元素等操作。

stack常用功能函数如下:

#include <iostream>
#include <stack>
#include <algorithm>
using namespace std;

/*Menu
03-0- stack输出
03-1- stack 创建
*/

void StaPrint(stack<int> &s); //03-0
void StaCreate(); //03-1

//03-0
void StaPrint(stack<int> &s)
{
	cout<<'[';
	while(s.size()!=0)
	{
		if(s.size()==1)
		{
			cout<<s.top()<<']';
			s.pop();
		}else
		{
			cout<<s.top()<<',';
			s.pop();
		}
	}
	cout<<endl;
}
//03-1
void StaCreate()
{
	stack<int> s;
	s.push(1);
	s.push(2);
	s.push(3);
	StaPrint(s);
	cout<<s.size()<<endl;
}
void TestStaCreate()
{
	StaCreate();
}

int main(int argc, char const *argv[])
{
//03-1
	TestStaCreate();
	return 0;
}

 

4、queue

queue使用一种先进先出的容器,其不允许遍历操作,其有两个出口,queue允许新增元素、移除元素、从最底端加入、最顶端取出元素。

queue常用功能函数如下:

#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;

/*Menu
04-0 queue
04-1 queue创建方法
*/

void QuePrint(queue<int> &q); //04-0
void QueCreate(); //04-1

//04-0
void QuePrint(queue<int> &q)
{
	cout<<'[';
	while(!q.empty())
	{
		if(q.size()==1)
		{
			cout<<q.front()<<']';
			q.pop();
		}else
		{
			cout<<q.front()<<',';
			q.pop();
		}
	}
	cout<<endl;
}
//04-1
void QueCreate()
{
	queue<int> q;
	q.push(1);
	q.push(2);
	q.push(3);
	cout<<"front:"<<q.front()<<'\t'<<"back:"<<q.back()<<endl;
	QuePrint(q);
	cout<<q.size()<<endl;
}
void TestQueCreate()
{
	QueCreate();
}

int main(int argc, char const *argv[])
{
//04-1
	TestQueCreate();
	return 0;
}

 

5、list

list是双向开口的数据结构,其节点不保证在连续空间,相对于vector,其对资源利用更好,不浪费资源,其插入和删除都是常数时间。其不仅是一个双向链表,还是一个双向环状链表,所以它只需要一个指针便可以完整表现整个链表。其迭代器具备前移、后移的能力,其有一个重要性质:插入操作和接合操作(splice)都不会造成原有的list迭代器失效。

list常用功能函数如下:

#include <iostream>
#include <list>
#include <algorithm>
using namespace std;

/*Menu
05-0 list输出
05-1 list创建
05-2 
05-3 
*/

void ListPrint(list<int> &l);//05-0
void ListCreate();//05-1
void ListMethod();//05-2
void ListAlgorithm();//05-3

//05-0
void ListPrint(list<int> &l)
{
	list<int>::iterator it = l.begin();
	int i=0;
	for(;it!=l.end();it++,i++)
	{
		if(i==l.size()-1){
			cout<<*it;
		}else
			cout<<*it<<"->";
	}
	cout<<endl;
}
//05-1
void ListCreate()
{
	//case 1
	list<int> l;
	for(int i=0;i<10;i++)
	{
		l.push_back(i+1);
	}
	ListPrint(l);
	//case 2
	list<int> l2(10,10);
	ListPrint(l2);
	//case 3
	list<int> l3(l.begin(),l.end());
	ListPrint(l3);
}
void TestListCreate()
{
	ListCreate();
}
//05-2
void ListMethod()
{
	list<int> l;
	for(int i=0;i<10;i++)
	{
		l.push_back(i+1);
	}
	//case 1 逆序输出
	//list 不支持随机访问
	int i=0;
	for(list<int>::reverse_iterator it=l.rbegin();it!=l.rend();it++,i++)
	{
		if(i==l.size()-1){
			cout<<*it;
		}else
			cout<<*it<<"->";
	}
	cout<<endl;
	//case 2 插入节点
	list<int> l2;
	l2.push_back(11);
	l2.push_back(12);
	l2.push_back(13);
	l2.push_front(3);
	l2.push_front(2);
	l2.push_front(1);
	ListPrint(l2);
	//case 3 删除节点
	l2.pop_back();
	l2.pop_front();
	ListPrint(l2);
	//case 4 插入操作
	l2.insert(l2.begin(),1);
	l2.insert(l2.end(),13);
	ListPrint(l2);
	//case 5 remove 删除所有与elem值相匹配的元素
	// erase 参数为删除迭代器指向的位置
	l2.push_back(13);
	l2.remove(13);
	l2.erase(l2.begin());
	ListPrint(l2);
	//case 6
	if(!l2.empty())
	{
		cout<<"size:"<<l2.size()<<endl;
	}
	l2.resize(8);//比实际size大就补0
	ListPrint(l2); 
	l2.resize(3);//比实际size小就去前n个
	ListPrint(l2);
	l2.swap(l);
	cout<<"l:\t";
	ListPrint(l);
	cout<<"l2:\t";
	ListPrint(l2);
}
void TestListMethod()
{
	ListMethod();
}
//05-3
bool ListCompare(int val1,int val2)
{
	return val1>val2;
}
void ListAlgorithm()
{
	list<int> l;
	for(int i=0;i<10;i++)
	{
		l.push_back(i+1);
	}
	//case 1
	l.reverse();
	ListPrint(l);
	//case 2
	//sort() 不支持随机迭代器的无法使用系统中的sort函数,可以使用其自带sort功能
	l.sort();
	ListPrint(l);
	//case 3 从大到小
	//如果使用自定义类型,如类成员,必须使用自定义排序规则
	//同理,remove时候,也需要自定义删除规则
	l.sort(ListCompare);
	ListPrint(l);

}
void TestListAlgorithm()
{
	ListAlgorithm();
}

int main(int argc, char const *argv[])
{

//05-1
	//TestListCreate();
//05-2
	//TestListMethod();
//05-3
	TestListAlgorithm();
	return 0;
}

 

6、说明

当前已在mingw32(gcc 4.9.2)上测试通过。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STL之序列式容器 的相关文章

随机推荐

  • OR-Tool 报INFEASIBLE

    OR Tool 使用Minimum Cost Flows报 There was an issue with the min cost flow input Status Status INFEASIBLE 这是因为node的编号需要是连续的
  • 肺炎疫情攻防战--肺炎X光病灶识别 Pytorch baseline

    肺炎疫情攻防战 肺炎X光病灶识别 Pytorch baseline 刚从Keras转Pytorch没多久 一边看着文档一边Google完成这比赛的baseline 比赛地址 比赛简介 本次由2019 nCoV病毒引发的肺炎疫情仍在持续 AI
  • 使用Hugging Face管道轻松应用NLP预训练模型

    这一段时间在研究自然语言处理 一直想找一些预训练模型 发现这个非常全 就收藏好好研究 作者 Robin van Merle 编译 VK 来源 Towards Data Science 原文链接 https towardsdatascienc
  • VMware中NET模式无法获取IP地址

    0x00 打开我的kali尝试运行脚本时 发现无论是桥接还是NET都无法获取到IP地址 经过各种百度以及尝试 最终解决 因此在此写下文章来记录一下 如果你也遇到相同问题 希望可以帮助到你 0x01 先看一下在NET下无法获取到地址的情况 此
  • react-create-app 基于 react-app-rewired scss设置全局变量全局函数

    目录 重写react脚手架配置 使用 scss 引用全局 scss 文件中的变量和函数应用全局 测试 重写react脚手架配置 customize cra 合并配置 react app rewired 重写react脚手架配置 安装依赖 n
  • 镜头桶形失真校正算法

    短焦镜头通常会产生桶形失真 以下是校正算法的matlab代码 cpp view plain copy 镜头桶形失真校正 短焦镜头 img origin1 imread Still001 bmp img origin rgb2gray img
  • day01fs模块

    一 文件操作 一 文件删除 1 异步 fs unlink path callback fs unlink hello txt err gt console lo err 回调函数参数err返回错误信息或者null 2 同步 fs unlin
  • 计算机enter代表什么意思,enter是什么意思

    手机评站网今天精心准备的是 enter是什么意思 下面是详解 电脑上键盘上enter是什么意思 在电脑键盘上带有 Enter 字样并有一弯箭头的按键 被叫做 回车键 其形状如下图所示 其位置在引号键的右边 另一个位置在数字键盘的右下角 在文
  • vue结合Waterfall做图片瀑布流展示

    一 安装Waterfall npm install vue waterfall plugin s 二 在组件中引入并使用
  • winform 程序的配置文件——App.config

    winform 程序的配置文件 App config Posted on 2005 09 26 17 11 sashow 阅读 668 评论 3 编辑 收藏 引用 网摘 所属分类 c 编程 在做 web 项目的时候 我一直在用 web co
  • 机器学习——1.Sklearn:特征工程

    目录 scikit learn数据集API介绍 sklearn小数据集 sklearn大数据集 sklearn数据集的使用 数据集的划分 特征工程 特征抽取 特征提取 特征提取API 字典特征提取 文本特征提取 中文文本特征值抽取 停用词
  • 线程池和连接池

    线程池 1 流程 先启动若干数量的线程 并让这些线程都处于睡眠状态 当客户端有一个新请求时 就会唤醒线程池中的某一个睡眠线程 让它来处理客户端的这个请求 当处理完这个请求后 线程又处于睡眠状态 2 作用 线程池作用就是限制系统中执行线程的数
  • Android MD5加密算法

    Android MD5加密算与J2SE平台一模一样 因为Android 平台支持 java security MessageDigest这个包 实际上与J2SE平台一模一样 算法签名 String getMD5 String val thr
  • IDEA连接MySQL

    今天使用IDEA连接MySQL时 遇到了很多问题 寻找了一个多小时终于把解决了 写篇博客记录记录 帮后来人节约时间 首先是参照其他帖子不断寻找Database视图 找了小半天才发现这个在IDEA中社区版是没有的 需要下载IDEA 的Ulti
  • 【allegro 17.4软件操作保姆级教程一】软件操作环境设置

    文中截图为16 6的软件截图 16 6与17 4的操作逻辑基本相同 大家无需担心 后续文章会使用17 4的截图 1操作环境准备1 1单位设置 可以将全局单位设置为mil 精度改为2位 也可以设置为mm 这时精度改为4位 这个根据习惯而定 操
  • PyTorch学习笔记(21) ——损失函数

    0 前言 本博客内容翻译自纽约大学数据科学中心在2020发布的 Deep Learning 课程的Activation Functions and Loss Functions 部分 废话不多说 下面直接开始吧 1 损失函数 本文是PyTo
  • 在Unity开发中使用 Rider

    Unity开发中使用Rider 环境 Windows Unity 2017 JetBrains Rider 2018 3 4 作为Windows和Visual Studio的拥趸 我是多么推崇Visual Studio 开发Unity使用
  • JS和Java实现链表类的基本功能

    综合网上实例 参考 http www 2cto com kf 201204 126773 html JavaScript实现参考 http m blog csdn net blog caiwenfeng for 23 8496029 Jav
  • 【C++入门到精通】C++入门 —— deque(STL)

    阅读导航 前言 一 deque简介 1 概念 2 特点 二 deque使用 1 基本操作 增 删 查 改 2 底层结构 三 deque的缺陷 四 为什么选择deque作为stack和queue的底层默认容器 总结 温馨提示 前言 文章绑定了
  • STL之序列式容器

    STL之序列式容器 STL容器即是将运用最广的一些数据结构实现出来 根据其在容器的排列特性 将其分为序列式容器和关联是容器 本文主要记录序列式容器 以及其常用的功能函数 1 vector vector和数组一样维护了一个连续的线性空间 ve