c++常用STL总结二(平衡二叉树multiset)

使得对数据结构的添加、删除、查找操作复杂度都限制在log(n)中,在STL中体现为multiset set multimap map四种排序容器中
multiset set 头文件:
multimap map 头文件:

文章涉及multiset set multimap map几种容器的遍历方法:只能借助于迭代器
multiset::iterator p;
p是迭代器,相当于指针,可++,–,用!=和==比较,不可以比较大小,不可以加减整数,不能相减(与指针不一样,有些容器几乎跟指针一模一样)

四种排序容器

multiset

multisetst; 能自动排序,开始st为空
排序规则:表达式"a<b"为true,则a排在b前面(相当于从小到大的顺序排列)
添加元素:st.insert()
查找元素:st.find()
删除元素:st.erase()

	multiset<int>st;
	int a[10] = { 2,6,7,3,9,5,6,8,3,9 };
	for (int i = 0; i < 10; i++)
	{
		st.insert(a[i]);
	}
	multiset<int>::iterator i;    //容器借助迭代器遍历元素,相当于指针
	for (i = st.begin(); i != st.end(); i++)
		cout << *i << " ";
	cout << endl;
	//输出:2 3 3 5 6 6 7 8 9 9  排好序的
	i= st.find(2);  //find 返回值为指向要查找元素的迭代器,若元素不存在就指向end()
	if (i == st.end())  cout << "Not Found" << endl;
	else cout << *i << endl;

multiset可以自定义排序规则
multiset<int, greater>st----------排序规则为从大到小
multiset<int ,Rule()>st;-----------自定义排序规则

find(x):在排序容器中找一个y,使得“x必须排在y”和“y必须排在x前面”都不成立,不是一般的"==",要按照排序规则来分析

set

set和multiset的区别在于容器里不能有重复元素
a和b重复:“a必须排在b前面”和“b必须排在a前面”都不成立

set插入元素可能不成功(不能插入容器中已经有的元素)
set的用法:

	set<int>my_set;
	int a[6]={4,7,4,9,7,6};
	for(int i=0;i<6;i++)
	my_set.insert(a[i]);
	set<int>::iterator i;
	for(i=my_set.begin();i!=my_set.end();i++)
	cout<<*i<<" ";    //输出4 6 7 9 无重复元素 
	cout<<endl;
	
	//由于set很可能插入不成功,所以插入元素以后需要判断
	pair<set<int>::iterator,bool>res=my_set.insert(8);
	/*
	pair这个数据类型相当于
	struct pair
	{
		set<int>::iterator first;    //返回指向插入元素位置的迭代器 
		bool second;       			//返回插入是否成功 
		含有两个数据成员,分别为pair<T1,T2> 的两个变量T1,T2; 
	}
	
	*/
	if(!res.second)   cout<<*res.first<<"already exists"<<endl;
	else cout<<*res.first<<"inserted"<<endl;

multimap

multimap容器里的元素,都是pair形式的,
multimap<T1,T2>mp;
struct
{
T1 first; //关键字(键)
T2 second; //值
};

mulrimap中的元素按照first排序,并可以按first进行查找,缺省的排序规则是"a.first <b.first" 为true,则a排在b前面

适用于需要频繁添加、删除元素,查找元素的程序,并且元素一直都是有序的,使用multimap效率高

案例:学生成绩录入,包含学生姓名、学生学号,学生成绩,学生学号是唯一的,姓名和分数都不唯一,程序有两种输入,分别为添加信息"Add name id score"和查询信息"Query score"交替出现,查询信息时为查询小于输入分数的最大分数对应学生的信息,如果有多个符合条件的信息输出学号最大的那个

由于程序需要不断的添加信息和查询信息,为了数据更大时的效率更高并且是以分数为关键字进行查询,则选择multimap数据结构

#include<bits/stdc++.h>
#include<map>   //multimap 和map需要包含的头文件 
using namespace std;
struct Info      //定义学生信息结构体 
{
	string name;
	int id;
};
struct Stu      //定义分数(关键字)-- 信息(值)结构体,相当于multimap类型 
{
	int score;
	Info  info;
};
typedef multimap<int,Info> MAP;
int main()
{
	MAP mp;
	Stu stu;
	char cmd[20];
	while(cin>>cmd)
	{
		if(cmd[0]=='A')
		{
			cin>>stu.info.name>>stu.info.id>>stu.score;
			mp.insert(make_pair(stu.score,stu.info));
			//make_pair生成一个pair<int,Info> 变量
			//其first等于st.score,second等于st.info 
		}
		else if(cmd[0]=='Q')
		{
			int score;
			cin>>score;
			MAP::iterator p=mp.lower_bound(score);     //用lower_bound来查找比score低的最大的分数对应的学生信息
														//表示[bgein(),p) 的学生分数都比score低,但是p所指向的不会比score低(大于等于score) 
			if(p!=mp.begin())      //表示找到了满足条件的学生 
			{
				p--;         //从第一个满足条件的学生开始遍历 
				int sco=p->first;
				int max=p->second.id;
				MAP::iterator t_mp=p;
				while((p!=mp.begin())&&(p->first==sco))  //遍历所有分数相同的学生 
				{
					if(p->second.id>max)
					{
						t_mp=p;
						max=p->second.id;	
					} 
					p--;
				}
				cout<<t_mp->second.name<<" "<<t_mp->second.id<<" "<<t_mp->first;
			}    //不能直接写t_mp->info(不存在这个数据成员,要写t_mp->second); 
			else cout<<"not found"<<endl;   //表示没有比score低的学生 
		}
	} 
	return 0;
}

map

不能有关键字重复的元素,重复元素表示两个个元素谁在前谁在后都可以
可以使用[],下标为关键字,返回值为first和关键字相同的元素的second(通过关键字查值)
插入元素可能失败,因为可能关键字已经存在了
更多内容参见这篇文章:

map详细用法

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值