关联容器 —— set、multiset、map、multimap

关联容器 :底层都是用红黑树(二叉排序树平衡树)实现前序遍历(左中右)排列有序,即根节点的左子树最小,右子树最大

 

红黑树插入方式:给红黑树插入节点1、2、3、4时。

先开辟一个节点,插入1,左子树和右子树为空;再构造2的节点(即再开辟一个节点,插入2)(如图1所示);要以前序遍历排列有序,将2和1进行比较,2大,进行树调整(如图2所示);再构造3的节点,不进行树调整,直接插入进去(如图3所示);再构造4的节点,将4和2进行比较,4大,进行树调整(如图4所示),3做根节点,2做根节点的左子树,1做2的左子树,4做3的右子树。现在以前序遍历有序。底层为红黑树的关联容器问题:再插入数据时,不断调整所有节点的位置,导致所有迭代器失效。

图1
图2

      

 

 

 

 

 

 

图3
图4

 

 

 

 

 

set 单重集合  multiset 多重集合

set 集合中的元素一定要能进行大小的比较

 

#include <iostream>
#include <set>
#include <iterator>
#include <algorithm>
using namespace std;

template<typename Container>
void show(Container& con)
{
	copy(con.begin(),con.end(),ostream_iterator<typename Container::value_type>(cout," ")); 
	cout << endl;
}

int main()
{

	set<int> st1;//set的构造方式一:不用传入参数(默认的构造函数) 
	int arr[] = {12,4,5,34,78,93,23};
	int len = sizeof(arr) / sizeof(arr[0]);
	set<int> st2(arr,arr+len);//set的构造方式二:通过数组构造集合对象
	show(st2);//打印直接有序 底层是二叉排序树

	//st1 是空集合 里面没有push方法 为什么? 针对树型结构给里面前插或后插或按位置插入没有意义,都会排序调整整个节点
	st1.insert(10);// set 插入数据
	st1.insert(10);// set 插入两个或以上相同数据时,实际输出只有一个 原因:set 是单重集合,不允许键重复
	show(st1);
	multiset<int> mst1;// multiset 多重集合,允许键重复
	mst1.insert(20);
	mst1.insert(20);
	show(mst1);

	st2.erase(93);// set 删除数据 有按值删、按迭代器区间删、按位置删三种重载
	st2.erase(st2.begin());
	st2.clear();// set 清空所有元素
	show(st2);

	//查找里面的元素,并给这个元素的位置插入一个数据
	set<int>::iterator sit = find(st2.begin(),st2.end(),12);
	if(sit == st2.end())
	{
		cout << "不存在" << endl;
	}
	if(sit != st2.end())
	{
		cout << "存在,插入数据" << endl;
		st2.insert(sit,444);//实际并没有在12的位置插入,插入后根据大小调整重新找位置
	}
	show(st2);
	return 0;
}

map 单重映射  multimap 多重映射

map 键值对的单重映射 只能一个键对应一个值,不允许值重复

#include <iostream>
#include <map>
#include <iterator> //迭代器头文件
#include <algorithm> //泛型算法头文件 本文件具体是 sort
using namespace std;
int main()
{
	 map<int,int> mp1;//map 的构造方式一:不用传入参数(所有的容器都支持默认的构造函数) 生成 mp1 映射对象
	                 //<int,int> 不仅要给出键的类型,还要给出值的类型 

	//int arr[] ={1,2,4,6,26,76,89,30};
	//int len = sizeof(arr) / sizeof(arr[0]);
	//map<int,int> mp2(arr,arr + len); //无法通过普通的迭代区间来构造 map 的对象

	// map 的插入一:按数据类型插入
	cout << typeid(map<int,int>::value_type).name() << endl;//打印出 map 里面的具体类型
	//struct std::pair<int const ,int>  map 里面是个 pair 的结构体,键类型为 int const, 值类型为 int
	typedef struct std::pair<int const ,int> PAIR;// 将 pair 的这个结构体重定义为 PAIR
	PAIR pair1(1,111);//用 PAIR 结构体生成变量 pair1,在里面传入数据 键指,数值 
	//相当于把 map 里面的一个节点构造好了,再把此节点插入 map 中
	mp1.insert(pair1);// 通过调用 mp1 的 insert,将 pair1 插入进去

	// map 的插入二:按值类型插入
	typedef map<int,int>::value_type VALUETYPE;//将 值类型重定义
	VALUETYPE val1(2,222);//用值类型生成值的对象 val1 在里面传入数据 键指,数值  
	mp1.insert(val1);
	
	// map 的插入三:通过赋值插入
	mp1[3] = 333;

	map<int,int>::iterator it = mp1.begin();
	for(it;it != mp1.end();it++)
	{
		cout << it->first << " ";//first表键 second表值
		cout << it->second << endl;
	}
	cout << endl;

	return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值