【STL】map和set的基本用法

本篇文章,主要通过了map和set的对比,介绍了STL中的map/set两种容器的用法以及区别;并介绍了map/set的底层实现原理;简单提及了一下关联式容器和顺序式容器的区别


pair

说明:

是一个结构体类型,里面的两个成员变量的类型可以通过模板给定;介绍pair的原因是,在map的insert方法中,需要插入pair类型的元素

定义:

template<class T1,class T2> struct pair;

模拟实现:

template<typename T1,typename T2>
struct Pair
{
	typedef T1 first_type;
	typedef T2 second_type;

	T1 first;
	T2 second;

	Pair()
		:first_type(T1())
		, second_type(T2())
	{}

	Pair(const T1 &x, const T2 &y)
		:first_type(x)
		, second_type(y)
	{}

	//拷贝构造函数
	template<typename U,typename V>
	Pair(const Pair<U, V> &p)
		: first(p.first)
		, second(p.second)
	{}
};

set

简介:

set是STL中的一个容器,和vector不同的是,set是一种关联式容器;

关联式容器的底层是用红黑树实现的;

红黑树是一颗近似平衡的搜索二叉树,在对元素的查找中有很高的效率;

其查询一个元素的时间复杂度为O(lg(N))

定义:


接口的使用:

<1>构造一个set类型的变量

set<int> s;

<2>insert() --- 插入一个元素


- 1 第一个insert返回的是一个pair类型的变量,其包含两个成员,第一个成员的类型是该map迭代器的类型,另一个成员的类型是bool

若map没有新插入的元素,那么插入成功,返回的是插入节点的迭代器以及TRUE;

若该元素在map中已经存在,那么插入会失败,返回的是该元素已经存在节点的迭代器,以及FALSE;

	//构造一个int类型的set
	set<int> s;

	//插入几个元素
	s.insert(1);
	s.insert(2);
	s.insert(6);

	//测试insert()的返回值
	pair<set<int>::iterator, bool> ret;
	ret = s.insert(4);//set中还没有4这个元素,插入成功,返回插入节点的迭代器和TRUE
	ret = s.insert(4);//set中已经存在了4,插入失败,返回的是元素4的迭代器和FALSE


- 2 该insert插入的是一段迭代器区间 

	//定义一段vector,类型也是int
	vector<int> v;
	v.push_back(10);
	v.push_back(50);
	v.push_back(5);

	//用insert向set s中插入该vector的全部
	s.insert(v.begin(), v.end());
<3>利用迭代器访问元素

	//定义一个对应类型的迭代器,指向s的起始
	set<int>::iterator it = s.begin();

	//当it没有指向s的最后一个元素的后一个元素时,访问
	while (it != s.end())
	{
		cout << *it << " ";
		it++;//迭代器自增,指向下一个元素
	}
	cout << endl;
反向迭代器也是类似的用法,这里就不多说了

<4>erase() ---删除一个元素或一段区间

- 1 用erase() 删除一个元素,传入删除元素的迭代器

- 2 用erase()删除一个元素,穿入一个key值,返回的是删除该key值节点的个数

- 3 删除一段迭代器区间


        //1.用find查找1这个元素,并用迭代器it获取返回值,然后进行删除
	set<int>::iterator it = s.find(500);

	if (it != s.end())                  //查询成功,则表示元素存在,删除该元素
		s.erase(it);
	else		              //若查询失败,表示不存在,对it解引用会是NULL
		cout << "没有找到" << endl;

	//2.直接删除一个key值
	s.erase(2);

	//3.删除一段迭代器区间
	s.erase(s.begin(), s.end());

<5>find() --- 用来查找一个元素,若查找到,则返回该元素对应的迭代器,否则返回最后一个元素的下一个元素


在删除的时候已经用过

<6>count() 

 统计一个元素的个数,在set中用于判断一个元素是否存在;因为无法插入相同的值,所以在set/map中与find的作用一样

<7>emplace()

emplace和insert都是向set中插入一个元素,但效率上看,emplace的效率要高一点

insert是先构造好,然后又经过一次拷贝构造放入set中;

而emplace是直接在set中进行构造


map

简介:

map也是一种关联式容器,与set不同的是,它是一种 Key/Value 结构的容器;

map的几种用途:

做英语词典、统计水果出现的个数

定义:


接口的使用:

<1> 定义一个map

map<string,int> countMap;

<2>insert() 

- 1 插入一个pair

map<string, int> m;
m.insert(pair<string, int>("hello", 0));
m.insert(pair<string, int>("world", 1));
- 2 插入一个value_type
m.insert(map<string, int>::value_type("change", 1));
- 3 利用数组下标进行插入,这里的K值需要是int
map<int, string> m;
m[0] = "first";
m[1] = "second";
m[2] = "third";

<3>erase() 元素的删除

- 1 迭代器删除

map<string, int>::iterator it = m.find("hello");
if (it != m.end())
m.erase(it);
- 2 key值删除

m.erase("hello");

<4> find() 查找元素

和set相同,查找成功返回对应的迭代器,否则返回最后一个元素的下一个位置

<5>count()

统计个数,但是由于不允许出现重复的Key值,所以和find()作用类似

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值