目录
前言
一、序列容器
1.1 vector容器
1.2 list容器、deque(双端队列容器)
二、vector向量容器
2.1 增删改查
三、关联容器
3.1 set容器、map容器、multiset、multimap
3.2 stack(栈) queue(队列) prority_queue(优先级队列)
四、map容器
4.1 pair关联容器
4.2 map(增删改查)
五、迭代器
5.1 常用 *** 作
5.2 遍历查找与删除
总结
前言
本篇总结了STL标准模板库 6大部分:容器、算法、迭代器、适配器、函数,对序列容器vector、关联容器map、迭代器指针进行了细致的探讨,对其原理、增删改查 *** 作、特点及区别以及不同情况下的不同结果进行了论证,更好的认识STL标准模板库!!
提示:以下是本篇文章正文内容,下面案例可供参考
头文件#include
功能:模拟了一个动态数组
底层实现:首先开辟一定大小的数组 随着元素的增加,如果空间不够之后 自动采取扩容机制
扩容规则:以原空间大小的2倍重新开辟一块空间 将就空间的元素挪到新空间上 在继续添加元素,一直遵循每次扩容大小是原空间大小的2倍
函数接口:vector常用接口 vector vec;由于vector底层是一个数组 所以其内存是连续的 可以采取下标访问方式
对于数组来说 尾插和尾删的时间复杂度为O(1);对于在容器头部或者中部插入或删除元素,则花费时间要长一些(移动元素需要耗费时间),时间复杂度为线性阶O(n)。
vector初始化方式:vector vec1;//默认方式初始化底层没有为其分配内存空间
vector vec2(10);//指定了刚开始的容量为10,默认值为0
vector primes {2,3,5,7,11,13,17,19};//含8个素数的 vector 容器
vector vec3(10,20);//指定了开始的容量10和每个格子的默认值为20
vector常用 *** 作:
v.capacity(); //容器容量
v.size(); //容器大小
v.max_size(): //表返回vector最大容量
v.at(int idx); //用法和[]运算符相同
v.push_back(); //尾部插入
v.pop_back(); //尾部删除
v.front(); //获取头部元素
v.back(); //获取尾部元素
v.begin(); //头元素的迭代器
v.end(); //尾部元素的迭代器
v.insert(pos,elem); //pos是vector的插入元素的位置
v.insert(pos, n, elem) //在位置pos上插入n个元素elem
v.insert(pos, begin, end);
v.erase(pos); //移除pos位置上的元素,返回下一个数据的位置
v.erase(begin, end); //移除[begin, end)区间的数据,返回下一个元素的位置
reverse(pos1, pos2); //将vector中的pos1~pos2的元素逆序存储
1.2 list容器、deque(双端队列容器)
二、vector向量容器
2.1 增删改查
***************************示例1:容器的初始化方式***************************
#include
#include //向量容器的头文件
using namespace std;
int main ()
{
//1.默认方式初始化底层没有为其分配内存空间
vector v;
//2.指定了刚开始的容量为10,默认值为0
vector v1(10);
//输出容器中元素的值 v1.size()获取元素的个数
for(int i =0;i v2(10,2);
for(int i =0;i v3(v2);
//5. CONFIG += c++11
vector v4 {1,2,3,4,5};
for(int i =0;i
#include
using namespace std;
int main()
{
//1.创建容器
vector v;//保存整型数据
//2.添加数据 模板类中的成员函数
v.push_back(10);//尾插
v.push_back(12);
v.push_back(13);
v.push_back(14);
v.push_back(16);
v[2] = 521;//修改对应角标位置的元素值 operator[] 函数的返回值是T&
//3.获取 输出 v.size()获取元素的个数
for(int i=0; i< v.size(); i++)
cout< v1;
for(int i=0;i<10;i++)
v1.push_back(i);
//向第二个元素位置 插入
v1.insert(v1.begin()+1,100);
cout< v;
int j = 0;
for(int i=0;i<=100;i++)
{
if(i%2 ==0)
{
v.push_back(i);//i=6 0
//改0
if(i%3 == 0)
{
v[j] = 0;
}
j++;
}
}
for(int i=0;i v;
for(int i=0;i<=100;i++)
{
if(i%2 ==0)
{
if(i%3 == 0)
v.push_back(0);
else
v.push_back(i);
}
}
for(int i=0;i v1;
for(int i=0;i<10;i++)
v1.push_back(i);
//获取头部元素
cout<
三、关联容器
红黑树的特性(了解):
(1)每个节点或者是黑色,或者是红色。
(2)根节点是黑色。
(3)如果一个节点是红色的,则它的子节点必须是黑色的。
(4)从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。[这里指到叶子节点的路径]
红黑树的优势:平衡查找二叉树
1.失掉了一部分平衡(保证在二倍以内即可)
2.比普通平衡查找二叉树,插入结点时,尽量在3次旋转内,插入到正确的位置,效率高,速度快
插入和删除的时间复杂度:logn
容器类自动申请和释放内存,无需new和delete *** 作。
map 通过关联容器保存数据,以键值对key-value形式存放数据 红黑树
map是存放pair的容器,根据pair中的first进行红黑树的排序。
first在map中又叫key,second又叫value。
Map是键-值对的集合,map中的所有元素都是pair,可以使用键作为下标来获取一个值。
Map中所有元素都会根据元素的键 (key)自动被排序,同时拥有实值value和键值key,
pair的第一元素被视为键值,第二元素被视为实值,同时map不允许两个元素有相同的键值。
3.1 set容器、map容器、multiset、multimap
声明及其初始化:pair pair也是一种模板类型。键(key)值(value)对它的数据成员是公有的,分别命名为first和second。
map m;//创建一个名为m的空map对象,其键和值的类型分别为key和value。
map m(m2);//创建m2的副本m,m与m2必须有相同的键类型和值类型。
**********************************示例1:pair关联容器******************************
#include
#include
#include
3.2 stack(栈) queue(队列) prority_queue(优先级队列)
四、map容器
4.1 pair关联容器
************************************示例代码:************************************
#include
#include
using namespace std;
int main()
{
map m;
// m.insert(pair("小明",18));
m.insert(pair("rose", 1));
m.insert(pair("tom", 2));
m.insert(pair("jerry", 3));
for(map::iterator iter = m.begin();iter != m.end();iter++)
{
cout<first<<" "<second<
#include
#include
#include
using namespace std;
int main(){
map mapst;
mapst.insert(pair(1,"student1"));
mapst.insert(pair(2,"student2"));
mapst.insert(pair(3,"student3"));
int nsize=mapst.size();
//此处应注意,应该是 for(int i = 1; i <= nsize; i++)
//而不是 for(int i = 0; i < nsize; i++) key为0的不存在
for(int i=1;i<=nsize;i++)
cout<
#include
#include
#include
using namespace std;
int main(){
map mapst;
mapst.insert(pair(1,"student1"));
mapst.insert(pair(2,"student2"));
mapst.insert(pair(3,"student3"));
int nsize=mapst.size();//3
//下标 mapst[key] -->对应的value
for(int i=1;i<=nsize;i++)
cout<key
mapst[10] = "helllo";//新建数据
cout<::iterator iter = mapst.begin();iter != mapst.end();iter++)
{
cout<first<<" "<second<::iterator iter = mapst.begin();iter != mapst.end();iter++)
{
cout<first<<" "<second<
#include
#include
using namespace std;
int main()
{
map m;
//关联容器的形式
m.insert(pair("小明",18));
//通过[]形式
m["小强"] = 20;
}
(二)用count函数来判定关键字是否出现,其缺点是无法定位数据出现位置,由于map的特性,一对一的映射关系,就决定了count函数的返回值只有两个,要么是0,要么是1,出现的情况,返回1了
例:count("小明")函数,0表示没有该key,1表示有而且数量就是1
#include
#include
using namespace std;
int main(){
map m;
//关联容器的形式
m.insert(pair("小明",18));
cout<
#include
#include
using namespace std;
int main(){
map m;
//关联容器的形式
m.insert(pair("小明",18));
map::iterator iter = m.find("小红");//find返回该key的迭代器对象
if(iter != m.end())
{
cout<first<<" "<second<first和 iterator->second分别代表关键字和存储的数据。
************************************示例:删除 ************************************
iterator erase(iterator it);//通过一个条目对象删除
iterator erase(iterator first,iterator last)//删除一个范围
size_type erase(const Key&key);//通过关键字删除
clear()就相当于enumMap.erase(enumMap.begin(),enumMap.end());
(一)从m中删除key为k的元素 m.erase(k)
int main()
{
pair p("aa",12);
map m;
m.insert(pair("xiao",16));
m.insert(pair("jack", 18));
m["aaa"] = 6;//
cout<::iterator iter = m.begin();iter != m.end();iter++)
{
cout<first<<" "<second< p("aa",12);
map m;
m.insert(pair("xiao",16));
m.insert(pair("jack", 18));
m.insert(pair("rose", 1));
m.insert(pair("tom", 2));
m.insert(pair("jerry", 3));
m["aaa"] = 6;
map::iterator iter = m.find("tom");
//通过迭代器删除
m.erase(iter);
for(map::iterator iter = m.begin();iter != m.end();iter++ )
{
cout<first<<" "<second<
4.2 map(增删改查)
1.底层原理:红黑树
2.map如何保存元素的? 键值对的方式存储
3.一个键值对是什么? pair关联容器
4.如何获取 键值对中的值? key -->p.first value --> p.second
5.map容器和pair(键值对)关系? map中可以存储 很多的键值对
6.关联容器特点:自动排序(默认升序)
7.map容器的特点:
1.键值对方式存储数据,并且按照key自动升序
2.插入的元素,key不可以重复
3.通过key 去查找 value cout<
using namespace std;
#include
int main()
{
//模板类型:key --> value 键值对 pair关联容器
// key value
pair p(1,"tom");
// key:1 second:tom
//cout< m;//插入 键值对(pair关联容器)
m.insert(/*键值对pair*/pair(2,"rose"));
m.insert(p);
//[]插入数据: m[key] = value;
m[13] = "jack";
m[4] = "lucy";
m[4] = "haha";
//cout<<"m[4]: "<::iterator it = m.find(4);
if(it != m.end())
cout<<"find:"<first<<" "<second<::iterator it1 = m.find(2);
if(it1 != m.end())
{
m.erase(it1);
}
//迭代器遍历,输出所有的元素
map::iterator iter;
for(iter=m.begin();iter!=m.end();iter++)
{
//*iter --> 键值对 pair关联容器
// key value
cout<<(*iter).first<<" "<second<
五、迭代器
迭代器:一种检查容器内元素并遍历元素的数据类型。C++更趋向于使用迭代器而不是下标 *** 作,因为标准库为每一种标准容器(如vector)定义了一种迭代器类型,而只用少数容器(如vector)支持下标 *** 作访问容器元素。C++中的迭代器是对指针的封装,迭代器提供特定的函数让调用者对指针进行特定的安全的 *** 作
定义和初始化:每种容器都定义了自己的迭代器类型,如vector:
vector::iterator iter; //定义一个名为iter的变量
每种容器都定义了一对名为begin和end的函数,用于返回迭代器。
迭代器初始化 *** 作:
vector ivec; //将迭代器iter1初始化为指向ivec容器的第一个元素
vector::iterator iter1=ivec.begin();
vector::iterator iter2=ivec.end();//初始化指向ivec容器的最后一个元素的下一个位置
注意:end并不指向容器的任何元素,而是指向容器的最后元素的下一位置,称为超出末端迭代器。
如果vector为空,则begin返回的迭代器和end返回的迭代器相同。
一旦向上面这样定义和初始化,就相当于把该迭代器和容器进行了某种关联,就像把一个指针初始化为指向某一空间地址一样。
示例:使用迭代器输出容器中的元素
vector::iterator iter;
//for(int i = 0; i< 10; i++)
//begin是容器的头元素 ,end并不是尾元素,而是无效的元素表示容器结束
for(iter = v.begin(); iter != v.end(); iter++)
{
cout<<*iter<<" ";
}
cout<
5.1 常用 *** 作
常用 *** 作:
*iter //对iter进行解引用,返回迭代器iter指向的元素的引用
iter->men //对iter进行解引用,获取指定元素中名为men的成员。等效于(*iter).men
++iter //给iter加1,使其指向容器的下一个元素
iter++
--iter //给iter减1,使其指向容器的前一个元素
iter--
iter1==iter2 //比较两个迭代器是否相等,当它们指向同一个容器的同一个元素或者都指向同一个容器 的超出末端的下一个位置时,它们相等
iter1!=iter2
5.2 遍历查找与删除
#include
#include //向量容器的头文件
using namespace std;
//参数:容器类型
vector& fun(vector& v1)//拷贝 同一个
{
//将容器第一个元素值改成 100
v1[0] = 100;
return v1;
}
//迭代器iterator(工具)遍历:对指针的封装
int main ()
{
vector v;
for(int i=0;i<10;i++)
{
v.push_back(i);//0~9
}
fun(v);
//v容器的迭代器
//类型 变量名
// vector::iterator iter;
//遍历 头 不到尾i<10 偏移
for(vector::iterator iter=v.begin(); iter != v.end();iter++)
{
// if(*iter %2 == 0)
// {
// *iter = 0;
// }
cout<<*iter< v1;
for(int i=0;i<10;i++)
v1.push_back(i);
vector::iterator iter = v1.begin()+1;
//v1.erase(iter);
v1.erase(v1.begin()+1,v1.end()); //移除[begin, end)区间的数据
for(int i=0;i::iterator iter = find(v.begin(), v.end(), 3);
3)注意:find方法只能删除找到的第一个元素
#include
#include
#include
using namespace std;
int main()
{
vector v;
for(int i = 0;i < 10;i++)
{
v.push_back(i);
}
vector::iterator iter = find(v.begin(), v.end(), 3);
v.erase(iter);
for(vector::iterator iter = v.begin();iter != v.end();iter++)
{
cout<<*iter<
#include
#include //算法头文件
using namespace std;
class Person
{
int age;
public:
Person(int age):age(age){}
void show(){cout< v;
//添加元素:3种方式
Person p(1);
//1.将对象装进容器
v.push_back(p);
Person p1(2);
v.push_back(p1);
//2.将匿名对象装进容器
v.push_back(Person(3));
//3.利用隐士转换方式 将对象装进容器
v.push_back(4);
for(int i=0 ; i< v.size(); i++)
v[i].show();//v[i]-->pesron对象
//迭代器遍历 调用show方法
vector::iterator iter;
for(iter=v.begin(); iter!=v.end(); iter++)
{
iter->show();//(*iter).show();
}
return 0;
}
*****************************示例:查找迭代器删除自定义类型***************************
#include
#include
#include
using namespace std;
class Person
{
int age;
public:
Person(int a):age(a){}
void show(){cout v;
Person p(10);
v.push_back(p);//Person(10)
v.push_back(Person(20));
v.push_back(Person(30));
vector::iterator it = find(v.begin(),v.end(),Person(20));
if(it != v.end())
{
it->show();
}else
cout<<"not"<::iterator iter = v.begin();iter != v.end(); iter++)
{
(*iter).show();//iter->show();
}
}
总结
总结了STL标准模板库 6大部分:容器、算法、迭代器、适配器、函数,对序列容器vector、关联容器map、迭代器指针进行了细致的探讨,对其原理、增删改查 *** 作、特点及区别以及不同情况下的不同结果进行了论证,更好的认识STL标准模板库!!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)