STL之关联容器

3 篇文章 0 订阅

1.set单重集合:不允许key重复

       set作为一个容器,也是用来存储同一数据类型的数据类型,并且能从一个数据集合中取出数据;C++ STL中标准关联容器set, multiset, map,multimap内部采用的就是一种非常高效的平衡检索二叉树:红黑树

  • 自动排序:在set中每个元素的值都唯一,而且系统默认的比较函数(小于函数)能根据元素的值自动进行排序(也可以自定义)。
  • 插入、删除效率高:因为使用的是红黑树,当插入删除集合元素(红黑树节点)时,挪动的是节点指针指向,不涉及内存移动,所以map和set的插入删除效率比用其他序列容器高、插入元素后迭代器也不会失效。
  • 查找效率高:在set中查找是使用二分查找,查找次数log2N。也就是说,如果有16个元素,最多需要比较4次就能找到结果,有32个元素,最多比较5次。那么有10000个呢?最多比较的次数为log10000,最多为14次,如果是20000个元素最多不过15次。
#include <iostream>
using namespace std;
#include <set>
template<typename container>
void show(container &con)
{
	container::iterator it= con.begin();
	while(it!=con.end())
	{
		std::cout<<*it<<" ";
		it++;
	}
	std::cout<<std::endl;
}
int main()
{
	int arr[]={12,33,534,45657,86576754,1};
	int len=sizeof(arr)/sizeof(arr[0]);
	std::set<int>myset(arr,arr+len);

	//show(myset);
	//默认排序后输出
	for (auto it = myset.cbegin(); it != myset.cend(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;


	//查询
	std::set<int>::iterator fit1=myset.find(12);   //二分查找
	std::set<int>::iterator fit2=std::find(myset.begin(),myset.end(),12);  //顺序遍历

        std::set<int,int>::iterator it1=myset.lower_bound(112);//返回第一个大于等于key_value的定位器
        std::set<int,int>::iterator it2=myset.upper_bound(112);//返回最后一个大于等于key_value的定位器

	//插入
	myset.insert(112);
	myset.insert(fit1,12);     //单重集合不允许键重复,虽然显示插入成功,但是集合还是只有一个12
	int count=myset.count(12);
	std::cout<<count<<endl;       //count=1;
        show(myset);

	//删除
	myset.erase(112);
        show(myset);
	myset.erase(myset.begin());
        show(myset);
 	myset.erase(myset.begin(),myset.end());
        show(myset);

	return 0;
}

结果: 

1 12 33 534 45657 86576754
1
1 12 33 112 534 45657 86576754
1 12 33 534 45657 86576754
12 33 534 45657 86576754

请按任意键继续. . .

2.multiset多重集合:允许key重复

3.map:单重映射:自动排序、插入/删除效率高、查找效率高

它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个称为该关键字的值)的数据处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。

#include <iostream>
using namespace std;
#include<algorithm>
#include <map>
template<typename container>
void show(container &con)
{
	container::iterator it= con.begin();
	while(it!=con.end())
	{
		std::cout<<*it<<" ";
		it++;
	}
	std::cout<<std::endl;
}

int main()
{
	//map单重映射key------>value
	std::map<int ,int>mymap;
	std::pair<int,int>p1(12,43);
	std::pair<int,int>p2(152,43);


	//插入数据:三种方法;前两种无区别,第三种数组[]插入方式的不同点在于:键值相同的会被后来插入的覆盖,而insert此时是插入不了
	mymap.insert(p1);	                   //插入之后还会按照键值大小排序
	mymap.insert(p2);

	mymap.insert(std::pair<int,int>(1,2));
	mymap.insert(std::pair<int,int>(1,3));  //插入失败,键值不能重复;
	mymap.insert(std::pair<int,int>(13,2));
	//判断是否插入成功:通过pair的第二个变量来知道是否插入成功,它的第一个变量返回的是一个map的迭代器,如果插入成功的话Insert_Pair.second应该是true的,否则为false。


	mymap[152]=456;
	mymap[52]=756;
	mymap[4]=56;
	mymap[5]=56;

	//输出map中的成员
	std::map<int,int>::iterator it=mymap.begin();
	while(it!=mymap.end())
	{
		std::cout<<"@   ";
		cout<<it->first<<" "<<it->second<<endl;  //@1  2     @12  43     @13  2     @152  43
		it++;
	}

	//也支持find,方法较多;
	std::map<int,int>::iterator iter=mymap.find(13);//利用返回的迭代器获取映射数据
	if(iter!=mymap.end())
	{
        std::cout<<"@   "<<iter->first<<"--->"<<iter->second<<endl;
	}
	//用count函数来判定关键字是否出现,出现返回1,否则返回0;


	//删除erase三种方法:按迭代器位置、按区间、按键值
	mymap.erase(mymap.begin());
	mymap.erase(iter);
	mymap.erase(mymap.begin(),mymap.end());

	return 0;
}

结果:

@   1 2
@   4 56
@   5 56
@   12 43
@   13 2
@   52 756
@   152 456
@   13--->2

请按任意键继续. . .

hash_map和map的区别:

  • 构造函数:hash_map需要等于函数;map只需要比较函数(小于函数).
  • 存储结构:hash_map采用hash表存储,map一般采用 红黑树(RB Tree) 实现;

什么时候需要用hash_map,什么时候需要用map

  • 总体来说,hash_map 查找速度会比map快,属于常数级别;而map的查找速度是log(n)级别。并不一定常数就比log(n)小,hash函数的耗时;在元素达到一定数量级时考虑hash_map。
  • 若你对内存使用特别严格,当你的hash_map对象特别多时,hash_map的构造速度较慢。

4.multimap:多重映射

它提供一对多(其中第一个可以称为关键字,每个关键字只能在map中出现多次,第二个称为该关键字的值)的数据处理能力

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值