map和set关联式容器特性(课堂笔记)

map和set都是关联式容器,它们有一些共同的特性:

1. 存储方式:map和set都是基于红黑树(Red-Black Tree)实现的,这使得它们内部的元素是有序的,根据特定的排序准则进行排列。

2. 唯一性:set中的元素是唯一的,任何两个元素之间都不相等。而在map中,每个键都是唯一的。

3. 查找效率:由于内部使用了红黑树实现,map和set都具有较高的查找效率,时间复杂度为O(log n)。

4. 插入和删除操作:对于插入和删除操作,同样由于红黑树的特性,map和set的操作效率也较高,时间复杂度也为O(log n)。

5. 没有随机访问:与vector和deque不同的是,map和set不支持通过下标随机访问元素,因为元素是按照排序规则存储的。

总的来说,map和set是高效的关联式容器,适合在需要进行快速查找、插入和删除操作,并且要求元素按照一定规则有序存储的情况下使用。
 



// set 底层是 key 模型搜索树 , 不允许重复 数值 , 不允许 修改
// 底层是 红黑树 实现  ,  时间复杂度为O(log n)

// 1.存储无序且不重复的元素
// 2.快速查找、删除和插入元素
// 3.去除重复元素
// 4.进行集合间的交集、并集、差集等操作

/*
#include<iostream>
#include<set>
#include<vector>
using namespace std;
void test1()// 作用
{
	set<int> s1;
	s1.insert(10);
	s1.insert(40);
	s1.insert(60);
	s1.insert(30);
	s1.insert(40);
	s1.insert(20);
	// 排序 + 去重
	set<int>::iterator it = s1.begin();
	while (it != s1.end())
	{
		cout << *it << " ";//10 30 40 60
		it++;
	}
	cout << endl;
}

void test2()// 构造 
{
	vector<int> v = { 2,6,4,1,4,5,9,8 }; 
	set<int> s(v.begin(), v.end());// set 支持 迭代区间的构造
	for (auto i : s)
	{
		cout << i << " ";
	}
	cout << endl;

	set<int> s1 = { 3,6,2,7,2,8,1 };// 支持 Initialist 构造
}

void test3()// 删除 
{
	set<int> s = { 3,6,2,7,2,8,1,5,4,9 };
	s.erase(4);//删除val
	for (auto i : s)
		cout << i << " ";
	cout << endl;

	auto i = s.find(7);
	s.erase(i);  // 删除位置
	for (auto i : s)
		cout << i << " ";
	cout << endl;
}

void test4()
{
	//迭代器区间删除
	set<int> s1 = { 10,20,30,40,50,60,70,80,90 };
	auto itlow = s1.lower_bound(25);// >= 25   itlow指向30     大于等于指定值的第一个元素的迭代器。
	auto itup = s1.upper_bound(60);//  >60     itup指向70      查找第一个大于指定值的元素的位置
	s1.erase(itlow, itup);
	for (auto i : s1)// [30,70) 左闭右开
		cout << i << " ";// 10 20 70 80 90
	cout << endl;
}
int main()
{
	//test1();
	//test2();
	//test3();
	test4();
	return 0;
}
*/



// multiset  底层也是 排序二叉树
// 允许冗余,只实现 排序操作

/*
#include<iostream>
#include<set>
#include<vector>
using namespace std;
int main()
{
	multiset<int> s1 = { 1,3,5,5,4,2,1,3 };
	for (auto i : s1)
		cout << i << " ";//1 1 2 3 3 4 5 5
	s1.erase(3);//默认查找 中序的第一个 key
	return 0;
}
*/


//例题1:  找两个数组的交集                       例2:找差集
//相等就是交集,记录下来,it1,it2++              相等就是交集,直接跳过,it1,it2++ 
//不相等,it1,it2小的++,一个到尾就结束            不相等,录入小的,it1,it2小的++,一个到尾就结束
/*
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
	set<int> s1(nums1.begin(), nums1.end());
	set<int> s2(nums2.begin(), nums2.end());
	vector<int>ans;
	auto it1 = s1.begin(), it2 = s2.begin();
	while (it1 != s1.end() && it2 != s2.end())
	{
		if (*it1 == *it2)
		{
			ans.push_back(*it1);
			it1++, it2++;
		}
		else if (*it1 < *it2)
			it1++;
		else
			it2++;
	}
	return ans;
}
*/






// map 是 key-value,模型
// 快速的查找功能,其内部实现通常基于红黑树 , 时间复杂度为O(log n)

// 1.快速查找:通过键来快速查找对应的值,可以有效加快数据查询的速度。
// 2.自动排序:map会根据键的大小自动对键值 key对进行排序,因此可以按顺序访问键值对。
// 3.唯一键:map中的键是唯一的,每个键只能对应一个值,可以确保数据的唯一性。
// 4.数据存储:可以用map来存储和管理键值对数据,提供了方便的数据组织方式。
// 5.字典:可以将map类比为字典,用键来索引值,方便进行数据管理和查找操作。


// key-value : key值不能修改,value可以修改

/*
#include<iostream>
#include<map>
#include<string>
using namespace std;

void test1()
{
	//构造
	map<string, string> dict;
	pair<string, string> kv1("sort", "排序");
	dict.insert(kv1);// 有名对象
	dict.insert(pair<string,string>("left","左边"));//匿名对象

	dict.insert(make_pair("right", "右边"));
	//等价与上,使用 make_pair 构造 pair

	dict.insert({ "String","字符串" });//隐式类型转换

	map<string, string> dict2 = { {"String","字符串"},{"left","左边"} };//隐式类型转换 + Initializer_list

	// iterator: key不能修改,value可以修改
	// const_iterator: 都不能修改``
	map<string, string>::iterator it = dict.begin();
	while (it != dict.end())
	{
		cout << (*it).first << ":" << it->second << endl;
		//cout << it.operator->()->first   编译器优化了
		++it;
	}
	cout << endl;

	for (auto& i : dict)//采用 引用减少复制
	{
		cout << i.first << ":" << i.second << endl;
	}
}


void test2()
{
	string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜",
"苹果", "香蕉", "苹果", "香蕉","苹果","草莓", "苹果","草莓" };
	map<string, int> countMap;
	for (auto& e : arr)
	{
		//auto it = countMap.find(e);
		//if (it != countMap.end())
		//{
		//	it->second++;
		//}
		//else //第一次出现
		//{
		//	countMap.insert({ e, 1 });
		//}
		countMap[e]++; //等价于上
		//V& operator[](const K& key)
		//{       
		//	 pair<iterator, bool> ret = this->insert(make_pair(key, V()));
		//   iterator it = ret.fisrt;
	    //	 return it->second;
		//}	 !!!!!!!!!!!!!!!!! 返回 value 的引用 !!!!!!!!!!!!!!!
		
	}
	for (auto& kv : countMap)
	{
		cout << kv.first << ":" << kv.second << endl;
		//草莓:2   苹果:8    西瓜 : 3    香蕉 : 2
	}
	cout << endl;

	// multimap 允许 key 冗余
	multimap<int, string> sortMap;
	for (auto& kv : countMap)
	{
		//sortMap[kv.second] = kv.first;// 草莓 被 香蕉 覆盖了 (使用 map_
 		sortMap.insert({ kv.second, kv.first });// key=2 重复,香蕉被 忽略了(使用 map)
	}
	cout << endl;
	// multimap 和 map 一样,会对 key 进行自动排序 
	for (auto& kv : sortMap)
	{
		cout << kv.first << ":" << kv.second << endl;
	}
	cout << endl;
}


// [] 作用
void test3()
{
	map<string, string> dict;
	dict.insert({ "string","字符串" });

	//插入
	dict["right"]; 
	
	//插入+修改
	dict["left"] = "左边";

	//查找
	cout << dict["string"] << endl;

	//修改
	dict["right"] = "右边";

	for (auto& i : dict)
	{
		cout << i.first << ":" << i.second << endl;
	}

	string str = "right";
	cout << dict.count(str) << endl;
	//打印 个数
}

int main()
{
	//test1();
	test2();
	//test3();
	return 0;
}

*/

简单的课堂笔记,去掉注释即可食用,注释什么的都在,诸君,加油!!!!!!!!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值