(五)STL剖析——set、map

简单了解了set、map的框架和接口

set

//所有元素都会根据键值进行排序,set不允许有两个相同的键值
//不能通过迭代器对set的元素进行修改,set的键值即实值,实值即键值,底层为const
//set使用红黑树的insert_unique(),mutilset才能使用insert_equal()
//关联式容器进行查找时最好使用其自己提供的find,而不是STL算法find

template<class T1, class T2>
struct Pair
{
	T1 first;
	T2 second;
	Pair()
		:first(T1())
		, second(T2())
	{}
	Pair(const T1& a, const T2& b)
		:first = a
		, second = b
	{}
};
template<class K,class Compare=Less<K>,class Alloc=alloc>//缺省采用递增排序
class Set
{
private:
	template<class T>
	struct Identity :public UnaryFunction<T, T>//unary_function<T, T>定义于<stl_function.h>
	{
		const T& operator(const T& x)const
		return x;
	};
	typedef RBTree<K, V, Identity<V>, Compare, Alloc> RepType;
	RepType t;//用红黑树来表示set
public:
	typedef typename RepType::ConstIterator Iterator;//表示无法通过set的迭代器进行修改
	typedef K ValueType;
public:
	Iterator Begin();
	Iterator End();
	void Clear();
	bool Empty()const;
	size_t Count(const K& key);
	size_t Size()const;
	void Swap(Set<K,Compare,Alloc>& s);

	Pair<Iterator,bool> Insert(const K& key);
	Iterator Insert(Iterator pos,const K& key);
	template<class InputIterator>
	void Insert(InputIterator first,Iterator last);

	size_t Erase(const K& key);
	void Erase(Iterator pos);
	void Erase(Iterator first,Iterator last);

	Iterator Find(const K& key)const;
};

Map

//map的所有元素都是pair,pair的第一元素称为键值,第二元素称为实值
//map会根据其键值进行排序,不允许两个相同的键值
//map不可以通过迭代器修改其键值,但可以修改其实值

template<class T1,class T2>
struct Pair
{
	T1 first;
	T2 second;
	Pair()
		:first(T1())
		, second(T2())
	{}
	Pair(const T1& a, const T2& b)
		:first = a
		,second = b
	{}
};
template<class K,class T, class Compare = Less<K>, class Alloc = alloc>//缺省采用递增排序
class Map
{
private:
	typedef RBTree<K, V, Selectlst<V>, Compare, Alloc> RepType;
	RepType t;//以红黑树表现Map

	typedef Map<K, T, Compare, Alloc> Self;
public:
	typedef Pair<const K, T> ValueType;
	typedef typename RepType::Iterator Iterator;//它不像Set一样将迭代器定义为ConstIterator
public:
	Iterator Begin();
	Iterator End();
	size_t Count(const T& x)const;
	bool Empty()const;
	size_t Size()const;
	void Swap(Self& m);
	void Clear();

	Pair<Iterator, bool> Insert(const ValueType& value);
	Iterator Insert(Iterator pos,const ValueType& value);//Position of the first element to be compared for the insertion operation.
	template<class InputIterator>
	void Insert(InputIterator first, InputIterator last);

	size_t Erase(const K& key);
	void Erase(Iterator pos);
	void Erase(Iterator first, Iterator last);

	Iterator Find(const K& key);

	T& operator[](const K& key)
	{
		return ((*(Insert(ValueType(key, T()))).first).second);
	}
};

时间: 2024-10-10 05:22:02

(五)STL剖析——set、map的相关文章

STL源码剖析(set/map)

SGI STL中set/map底层都是通过RB-tree实现的. 首先看看RB-tree结点的定义 1 typedef bool __rb_tree_color_type; 2 const __rb_tree_color_type __rb_tree_red = false; 3 const __rb_tree_color_type __rb_tree_black = true; 4 5 // 结点的基类 6 struct __rb_tree_node_base 7 { 8 typedef __

STL 中的map 与 hash_map的理解

可以参考侯捷编著的<STL源码剖析> STL 中的map 与 hash_map的理解 1.STL的map底层是用红黑树存储的,查找时间复杂度是log(n)级别: 2.STL的hash_map底层是用hash表存储的,查询时间复杂度是常数级别: 3.什么时候用map,什么时候用hash_map? 这个要看具体的应用,不一定常数级别的hash_map一定比log(n)级别的map要好,hash_map的hash函数以及解决地址冲突等都要耗时,而且众所周知hash表是以空间效率来换时间效率的,因而h

NHibernate 集合映射深入 (第五篇) &lt;set&gt;,&lt;list&gt;,&lt;map&gt;,&lt;bag&gt;

NHibernate 集合映射深入 (第五篇) <set>,<list>,<map>,<bag> 一.集合外键 在NHibernate中,典型的用于映射集合类的元素有<set>,<list>,<map>,<bag>,<array>,<primitive-array>. 我们回到上一篇,集合映射基础当中的一对多查询.对于集合类型: public virtual ISet<Person

重读STL源码剖析:map与set

map与set底层都是调用的RBTree 首先看RBTree RBTree 红黑树的特性: 1.根节点为黑色 2.新增节点一定是红色 3.节点只有红色或黑色两种颜色 4.两个节点颜色不能同为红 5.任意一条路径上的黑色节点个数相同 红黑树的节点设计: 1.表示节点颜色的变量color 2.链接左子树的left指针 3.链接右子树的right指针 4.链接父节点的parent指针 5.表示节点值的变量value_field;在map中为pair对,在set中只有key RBTree的迭代器: 1.

STL容器之map与hash_map

一.简介 就应用来说,map已经是STL标准库的成员,而hash_map暂时还未进入标准库,是扩展ext中的一个功能,但也是非常常用并且非常重要的库. 二.简单对比 首先,要说的是这两种数据结构的都提供了KEY-VALUE的存储和查找的功能.但是实现是不一样的,map是用的红黑树,查询时间复杂度为log(n).而hash_map是用的哈希表,查询时间复杂度理论上可以是常数,但是消耗内存大,是一种以存储换时间的方法. 树查找,在总查找效率上比不上hash表,但是它很稳定,它的算法复杂度不会出现波动

STL容器——对map排序

STL容器(三)——对map排序 对于map的排序问题,主要分为两部分:根据key排序:根据value排序.下面我们就分别说一下~ 1. 根据key进行排序 map默认按照key进行升序排序 ,和输入的顺序无关.如果是int/double等数值型为key,那么就按照大小排列:如果是string类型,那么就按照字符串的字典序进行排列~ (还记得之前说过的字典序吗?当时我们用到了next_permutation这个库函数!)下面我们展示一个例子,说明map中默认按照key升序排列 的情况. Exam

关于STL中的map和hash_map

以下全部copy于:http://blog.chinaunix.net/uid-26548237-id-3800125.html 在网上看到有关STL中hash_map的文章,以及一些其他关于STL map和hash_map的资料,总结笔记如下:     1.STL的map底层是用红黑树实现的,查找时间复杂度是log(n):     2.STL的hash_map底层是用hash表存储的,查询时间复杂度是O(1):     3.什么时候用map,什么时候用hash_map?     这个药看具体的

初识STL 剖析list部分源码

1.STL    库函数的设计第一位是通用性,模板为其提供了可能:标准模板库中的所有算法和容器都是通过模板实现的.  STL(标准模板库)是 C++最有特色,最实用的部分之一. STL整个架构模型如下: 2.list(双向循环链表) 调用STL系统的#include<list>,用系统的双向循环链表结构处理: #include<iostream> #include<list> //调用系统的list,双向循环链表结构 using namespace std; int m

STL中关于map和set的四个问题?

STL map和set的使用虽不复杂,但也有一些不易理解的地方,如: # 为何map和set的插入删除效率比用其他序列容器高? # 为何每次insert之后,以前保存的iterator不会失效? # 为何map和set不能像vector一样有个reserve函数来预分配数据? # 当数据元素增多时(10000到20000个比较),map和set的插入和搜索速度变化如何? 或许有得人能回答出来大概原因,但要彻底明白,还需要了解STL的底层数据结构. C++ STL 之所以得到广泛的赞誉,也被很多人