set与multiset

set和Multiset会根据特定的排序规则自动将元素排序,multiset允许元素重复,set不允许元素重复,二者在std中定义如下:

namespace std
{
	template <class T,
						class Compare = less<T>,
						class Allocator = allocator<T>>
	class set ;	
	
	template <class T,
						class Compare = less<T>,
						class Allocator = allocator<T>>
	class multiset ;	
	}
可有可无的排序准则,当我们没有传入排序准则时,就会采用less---这是一个访函数,以operator<对元素进行比较,一边完成排序

第三个参数定义了内存模型,默认是allocator

和所有标准关联式容器类似,set,multiset通常使用平衡二叉树实现

ps:1.事实上set和multiset通常使用红黑树(red-black tree)实作而成,红黑树在改变元素数量和元素搜索方面都很出色,他保证节点安插时最多只会作两个重新连接动作,而且到达某一元素的最长路径深度,最多只是最短路径深度的两倍。

2.标准的STL序列容器包括:vector、list、deque、heap(算法呈现)、stack(适配器)、queue(适配器)、priority_queue(适配器)。
标准的STL关联式容器包括:set、multiset、map、multimap。
SGI STL还提供了一些非标准的关联式容器,eg:hash_table、hash_set。

3.二叉搜索树是一种特殊的二叉树,其具有如下性质:
1) 若左子树不空,则左子树所有结点的值均小于它的根结点的值
2)若右子树不空,则右子树所有节点的值均大于它的根节点的值
3)左右子树也分别为二叉搜索树
二叉搜索树支持各种动态集合操作,包括:插入、查找、删除,其操作的时间复杂度与树的高度成正比,在遇到二叉树极端不平衡的情况下,其形状就与链表是一样的,二叉树插入、查找、删除的时间复杂度都退化为O(n)。
平衡二叉搜索树是一种特殊的二叉搜索树,其没有一个节点深度过大,不同的平衡条件,造就不同的效率表现。常见的平衡二叉搜索树有:AVL-tree和RB-tree。
关联容器一般以平衡二叉搜索树作为内部数据结构,RB-tree的应用尤其广泛。
RB-tree
是许多平衡二叉查找树的一种,一颗有n个内结点的红黑树的高度至多为2lg(n+1),
它能保证在最坏情况下,基本的动态集合操作时间为O(lgn)。

自动排序主要优点是使搜索元素时具有良好的性能,具有对数复杂度。但是自动排序造成的一个限制是:不能直接改变元素值,因为这样会改变原来的顺序,要想改变的话必须先删除原来的元素,再插入一个新的元素。


c.rbegin()----逆向迭代器,指向逆向遍历时的第一个元素

c.rend()----逆向迭代器,指向遍历时的最后元素的下一个位置

c.insert(elem)----插入elem的副本,返回位置

c.insert(pos,elem)---插入elem,返回位置信息,pos是个提示信息,如果恰当会加快速度

c.insert(beg,end)---将区间[beg,end)的元素插入进去

c.erase(elem)---删除值为elem的元素,返回被删除的个数

c.erase(pos)---移除迭代器pos上的元素

c.erase(beg,end)---移除区间[beg,end)内的所有元素,无返回值

c.clear()---移除所有元素,将容器清空

  • set提供如下接口

pair<iterator,bool> insert(const value_type& elem) ;

iterator                     insert(iterator pos_hint, const value_type& elem) ;

  • multiset提供如下接口

iterator insert(const value_type& elem) ;

iterator insert(iterator pos_hint, const value_type& elem) ;

#include <iostream>
#include <set>
#include <iterator>
using namespace std;
int main()
{
	typedef set<int, greater<int>> IntSet ;//设置排序规则从大到小
	IntSet coll1 ;
	coll1.insert(4) ;
	coll1.insert(3) ;
	coll1.insert(5) ;
	coll1.insert(1) ;
	coll1.insert(6) ;
	coll1.insert(2) ;
	coll1.insert(5) ;
	IntSet::iterator pos ;
	for (pos = coll1.begin(); pos != coll1.end(); ++pos)
	{
		cout << *pos ;
	}
	cout << endl ;

	pair<IntSet::iterator, bool> status = coll1.insert(4) ;
	if (status.second)
	{
		cout << "4 inserted as element"
			 << distance(coll1.begin(), status.first) + 1
			 <<endl ;
	}
	else//set不允许重复
	{
		cout << "4 already exits" << endl ;
	}
	set<int> coll2(coll1.begin(), coll1.end()) ;//coll2使用默认排序规则,从小到大
	copy(coll2.begin(), coll2.end(), ostream_iterator<int>(cout, " ")) ;
	cout << endl ;

	coll2.erase(coll2.begin(), coll2.find(3)) ;//find会返回迭代器的位置

	int num = coll2.erase(5) ;
	cout << num << "element removed" << endl ;

	copy(coll2.begin(), coll2.end(), ostream_iterator<int>(cout, " ")) ;
	cout << endl ;
	system("pause") ;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值