#STL中的平衡二叉树数据结构set&&multiset

*目的:有时需要快速大量增加、删除数据的同时,还要进行大量数据的查找。
*希望增加数据、删除数据、查找数据都能在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;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值