*目的:有时需要快速大量增加、删除数据的同时,还要进行大量数据的查找。
*希望增加数据、删除数据、查找数据都能在log(n)复杂度完成
*排序+二分查找显然不可能,因加入新数据就要重新排序
*可以使用“平衡二叉树”数据结构存放数据,体现在STL中,就是以下四种“排序容器”:multiset &set &multimap &map
(就是使用该容器的时候,边添加边自动排序了,很方便了)
第一种容器:multiset
用法:
multiset<T> st;
1)定义了一个multiset变量st,st里面可以存放T类型的数据,并且自动排序。开始st为空.
2)排序规则:表达式“a<b”为true则a排在b前面
3)可用st.insert添加元素,st.find查找元素,st.erase删除元素,复杂度都是log(n)
#include<iostream>
#include<cstring>
#include<set>//使用multiset与set时需要的头文件
using namespace std;
int main()
{
multiset<int> st;//意味着容器里都是int类型的变量
int a[10]={1,14,12,13,7,13,21,19,8,8};
for(int i=0;i<10;++i)
st.insert(a[i]);//a[i]本身没放进去,插入a[i]的复制品
//插入的时候里面的元素会自动排好序
multiset<int>::iterator i;//(若要遍历容器内元素)则需迭代器,类似指针
for(i=st.begin();i!=st.end();++i)
cout<<*i<<",";
cout<<endl;
//输出:1,7,8,8,12,13,13,14,19,21
i=st.find(22);//查找22,返回值是迭代器
if(i==st.end())//查找不到则返回值end()
cout<<"Not Found"<<endl;
//输出Not Found
st.insert(22);//插入22
i=st.find(22);
if(i==st.end()) cout<<"Not Found"<<endl;
else cout<<"Found"<<*i<<endl;//找到则返回指向找到元素的迭代器
//输出:found:22
i=st.lower_bound(13);
cout<<*i<<endl;
//输出13
i=st.upper_bound(8);
cout<<*i<<endl;
//输出12;
st.erase(i)//删除迭代器i指向的元素,即12
for(i=st.begin();i!=st.end();++i)
cout<<*i<<",";
return 0;
//输出1,7,8,8,13,13,14,19,21,22
}
如果排序规则为从大到小的话
格式:multiset<T,greater<T>> st
迭代器上写法:multiset<T,greater<T>>::iterator i;
如果需要自定义排序规律的话
struct Rule1{
bool operator()(const int &a,const int &b)
{
return (a%10)<(b%10);//返回值要求个位数从小到大排
}
};
那么用法:multiset<int,Rule1> st;
迭代器:multiset<int,Rule1>::iterator p;
浅谈muliset上的迭代器
multiset<T>::iterator p;
multiset上的元素需要通过multiset才可运行
p是迭代器,类似于指针,可用于指向multiset中的元素。访问multiset中的元素需要通过迭代器。
与指针不同的是:multiset上的迭代器可++,–,用!=和==比较,不可比大小,不可加减整数,不可相减。
st.begin()类型为
multiset<T>::iterator
是指向st中头一个元素的迭代器。
st.begin()类型同上
是指向st中最后一个元素后面的迭代器
对迭代器++,其就指向容器中下一个元素
第二种容器:set
*set和multiset的区别在于容器里不能有重复元素
*set插入元素可能不成功
#include<iostream>
#include<cstring>
#include<set>
using namespace std;
int main()
{
set<int> st;
int a[10]={1,2,3,8,7,7,5,6,8,12};
for(int i=0;i<10;++i)
st.insert(a[i]);
cout<<st.size()<<endl;
//输出8
set<int>::iterator i;
for(i=st.begin();i!=st.end();++i)
cout<<*i<<",";
//输出1,2,3,5,6,7,8,12
cout<<endl;
}
以上就是很基础的与multiset的区别。
下面我将展示一种新的模板:pair模板的用法
pair<T1,T2>类型等价于:
struct{
T1 first;
T2 second;
};
例如:pair<int,double> a;
等价于:
struct{
int first;
double second;
}a;
a.first=1;
a.second=93.3;
以上为引子,那么今天我想介绍pair在set中的使用(在multimap与map中也有讲,具体看下一篇):
因为
pair<set<int>::iterator,bool>
等价于
struct{
set<int>::iterator first;
bool second;
};
所以为了体现一个输入不成功(即set中已经有了的元素)的情况
pair<set<int>::iterator,bool>result=st.insert(2);
if(!result.second)//说明插入条件不成功
cout<<*result.first<<"Already exist"<<endl;
else
cout<<*result.first<<"insert"<<endl;
return 0;